-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Length on Send Functions, Expose KeepAlive, Finalize, etc #334
Implement Length on Send Functions, Expose KeepAlive, Finalize, etc #334
Conversation
Warning Rate limit exceeded@dvonthenen has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 44 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. WalkthroughThe pull request introduces modifications across multiple files in the Deepgram client libraries. Key changes include updates to the Changes
Possibly related PRs
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Outside diff range and nitpick comments (13)
Deepgram/Clients/Listen/v1/WebSocket/Constants.cs (2)
14-14
: Add documentation for the new constant.The purpose and usage of
UseArrayLengthForSend
are not immediately clear. Please add XML documentation to explain its intended use, especially considering its sentinel value of -1.Consider adding documentation like this:
/// <summary> /// Constant used to indicate that the full array length should be used when sending data. /// </summary> public const int UseArrayLengthForSend = -1;
20-21
: Approved. Consider adding more detailed documentation.The new constant
DefaultFlushPeriodInMs
is well-named and its value seems appropriate. However, to improve maintainability and usability, consider adding more detailed XML documentation.Here's a suggested documentation format:
/// <summary> /// The default flush period in milliseconds. /// </summary> /// <remarks> /// This value determines how often the buffer is flushed during data transmission. /// A lower value may increase responsiveness but could also increase network overhead. /// </remarks> public const int DefaultFlushPeriodInMs = 500;Deepgram.Microphone/Microphone.cs (2)
30-30
: LGTM: Constructor signature updated correctlyThe constructor signature has been correctly updated to match the new
_push_callback
field type. This change maintains consistency within the class and allows users to provide callbacks that can receive both the byte array and its length.Consider updating the XML documentation for the
push_callback
parameter to reflect the new signature:/// <param name="push_callback">A callback that receives the audio data as a byte array and its length</param>
123-123
: LGTM: Callback invocation updated correctlyThe
_push_callback
invocation has been correctly updated to passbuf.Length
as the second argument, which is consistent with the new callback signature. This ensures that the length information is accurately provided to the callback.Consider a minor optimization to avoid calculating the buffer length twice:
- byte[] buf = new byte[frameCount * sizeof(Int16)]; + int bufLength = (int)(frameCount * sizeof(Int16)); + byte[] buf = new byte[bufLength]; if (_isMuted) { - buf = new byte[buf.Length]; + buf = new byte[bufLength]; } else { - Marshal.Copy(input, buf, 0, buf.Length); + Marshal.Copy(input, buf, 0, bufLength); } - _push_callback(buf, buf.Length); + _push_callback(buf, bufLength);This change reduces redundant calculations and improves code readability.
Deepgram/Clients/Interfaces/v1/ISpeakWebSocketClient.cs (2)
112-112
: LGTM! Consider enhancing the documentation.The addition of the
length
parameter improves flexibility and aligns with the PR objectives. This change is backwards compatible and allows for more precise control over data transmission.Consider updating the method's XML documentation to include information about the new
length
parameter:/// <summary> /// Sends a binary message over the WebSocket connection. /// </summary> /// <param name="data">The data to be sent over the WebSocket.</param> /// <param name="length">The number of bytes to send. If not specified, the entire array length is used.</param> public void Send(byte[] data, int length = Constants.UseArrayLengthForSend);
Naming Inconsistencies Persist in ISpeakWebSocketClient Implementations
The implementations of
Send
,SendMessage
, andSendMessageImmediately
methods correctly include thelength
parameter, aligning with the interface changes. However, the naming and documentation inconsistencies identified earlier still exist:
- Methods like
SendMessage
suggest handling text but acceptbyte[]
parameters.- The distinction between
Send
andSendMessage
remains unclear.Addressing these inconsistencies will improve code clarity and maintainability.
🔗 Analysis chain
Line range hint
112-133
: Overall changes look good, but consider addressing naming inconsistencies.The addition of the
length
parameter to all send methods is consistent and aligns with the PR objectives. However, there are some naming and documentation inconsistencies that should be addressed:
- The methods
SendMessage
andSendMessageImmediately
suggest they handle text, but they acceptbyte[]
parameters.- The distinction between
Send
andSendMessage
is not clear from their signatures.Consider renaming these methods or adjusting their parameter types to better reflect their purposes. For example:
SendBinary
instead ofSend
SendText
(with astring
parameter) if it's meant for textSendBinaryImmediately
instead ofSendMessageImmediately
To ensure these changes are correctly implemented, please run the following script to check the usage of these methods in the implementation classes:
This script will help verify that the implementing classes have been updated to match the new interface signatures.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check the usage of ISpeakWebSocketClient methods in implementation classes # Search for classes implementing ISpeakWebSocketClient implementingClasses=$(rg --type csharp "class.*:.*ISpeakWebSocketClient" -l) # Check the implementation of each method for class in $implementingClasses; do echo "Checking implementation in $class" rg --type csharp "public void Send\(byte\[\] data, int length" "$class" rg --type csharp "public void SendMessage\(byte\[\] data, int length" "$class" rg --type csharp "public void SendMessageImmediately\(byte\[\] data, int length" "$class" doneLength of output: 968
Deepgram/Clients/Speak/v1/WebSocket/Client.cs (3)
Line range hint
364-387
: Consider adding parameter validation forlength
The
SendMessage
method has been updated to include thelength
parameter, which is then passed directly to theWebSocketMessage
constructor. However, there's no validation to ensure that thelength
value is valid (e.g., not negative or greater than the data array length).Consider adding a validation check for the
length
parameter before using it. For example:public void SendMessage(byte[] data, int length = Constants.UseArrayLengthForSend) { if (length != Constants.UseArrayLengthForSend && (length < 0 || length > data.Length)) { throw new ArgumentOutOfRangeException(nameof(length), "Length must be non-negative and not greater than the data array length."); } // ... rest of the method ... EnqueueSendMessage(new WebSocketMessage(data, WebSocketMessageType.Text, length)); }This validation will help prevent potential issues with invalid length values.
Line range hint
406-437
: LGTM: Proper handling oflength
parameter, but consider adding validationThe
SendMessageImmediately
method has been updated to correctly handle the newlength
parameter. The implementation properly checks for the default value and uses thelength
parameter in theArraySegment
constructor when sending the message.However, similar to the
SendMessage
method, there's no validation of thelength
parameter. Consider adding a validation check at the beginning of the method:public void SendMessageImmediately(byte[] data, int length = Constants.UseArrayLengthForSend) { if (length != Constants.UseArrayLengthForSend && (length < 0 || length > data.Length)) { throw new ArgumentOutOfRangeException(nameof(length), "Length must be non-negative and not greater than the data array length."); } // ... rest of the method ... }This validation will help prevent potential issues with invalid length values.
Line range hint
351-437
: Overall: Good implementation oflength
parameter, with some suggestions for improvementThe addition of the
length
parameter to theSend
,SendMessage
, andSendMessageImmediately
methods improves the flexibility of the WebSocket client, allowing for more control over the amount of data sent. The use ofConstants.UseArrayLengthForSend
as a default value maintains backward compatibility.Suggestions for improvement:
- Add parameter validation for the
length
parameter in all methods where it's introduced.- Consider adding a comment or documentation explaining the purpose and usage of
Constants.UseArrayLengthForSend
.- Evaluate the potential performance impact of these changes, especially for large messages, and consider adding a note in the documentation if there are any significant considerations.
To address these suggestions:
- Implement parameter validation as shown in previous comments.
- Add a comment explaining
Constants.UseArrayLengthForSend
:// Constants.UseArrayLengthForSend is a special value indicating that the entire data array should be sent. // When this value is used, the actual length of the data array will be used for sending the message.
- Add a note in the class or method documentation:
/// <remarks> /// The addition of the `length` parameter allows for sending partial data from the provided array. /// For large messages, consider the potential performance implications and use appropriate length values. /// </remarks>These improvements will enhance the robustness and clarity of the WebSocket client implementation.
Deepgram/Clients/Listen/v1/WebSocket/Client.cs (3)
317-336
: LGTM! Consider adding error handling.The new
SendClose
method is well-implemented, providing flexibility in how the close message is sent to Deepgram. The use of locking ensures thread safety, and the logging is helpful for debugging.Consider adding error handling for the
SendAsync
call within theif (nullByte && _clientWebSocket != null)
block. For example:if (nullByte && _clientWebSocket != null) { // send a close to Deepgram lock (_mutexSend) { - _clientWebSocket.SendAsync(new ArraySegment<byte>([0]), WebSocketMessageType.Binary, true, _cancellationTokenSource.Token) - .ConfigureAwait(false); + try + { + _clientWebSocket.SendAsync(new ArraySegment<byte>([0]), WebSocketMessageType.Binary, true, _cancellationTokenSource.Token) + .ConfigureAwait(false); + } + catch (Exception ex) + { + Log.Error("SendClose", $"Error sending close message: {ex.Message}"); + } } return; }This will ensure that any exceptions during the send operation are logged and don't disrupt the method's execution.
342-355
: LGTM! Consider updating method documentation.The changes to
Send
,SendBinary
, andSendMessage
methods are well-implemented. The addition of thelength
parameter provides more flexibility in controlling the amount of data sent, and the use of a constant for the default value is a good practice.Consider updating the XML documentation for these methods to reflect the new
length
parameter. For example:/// <summary> /// Sends a binary message over the WebSocket connection. /// </summary> /// <param name="data">The data to be sent over the WebSocket.</param> /// <param name="length">The number of bytes to send. If set to Constants.UseArrayLengthForSend, the entire array will be sent.</param> public void Send(byte[] data, int length = Constants.UseArrayLengthForSend) => SendBinary(data, length);Apply similar updates to the
SendBinary
andSendMessage
method documentations as well.
360-389
: LGTM! Consider adding bounds checking.The changes to
SendBinaryImmediately
andSendMessageImmediately
methods are well-implemented. The new logic correctly handles thelength
parameter, and the use ofArraySegment
ensures that only the desired amount of data is sent.Consider adding bounds checking to ensure that the
length
parameter is not greater than thedata.Length
. This will prevent potentialArgumentOutOfRangeException
. For example:public void SendBinaryImmediately(byte[] data, int length = Constants.UseArrayLengthForSend) { lock (_mutexSend) { Log.Verbose("SendBinaryImmediately", "Sending binary message immediately.."); // TODO: dump this message if (length == Constants.UseArrayLengthForSend) { length = data.Length; } + else if (length > data.Length) + { + Log.Warning("SendBinaryImmediately", $"Specified length {length} is greater than data length {data.Length}. Using data length instead."); + length = data.Length; + } _clientWebSocket.SendAsync(new ArraySegment<byte>(data, 0, length), WebSocketMessageType.Binary, true, _cancellationTokenSource.Token) .ConfigureAwait(false); } }Apply a similar change to the
SendMessageImmediately
method as well.Deepgram/Clients/Listen/v1/WebSocket/WebSocketMessage.cs (1)
14-28
: Consider adding XML documentation comments for new membersTo improve code readability and maintainability, consider adding XML documentation comments to the new constructor overload and the
Length
property. This will help other developers understand the purpose and usage of these members.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (10)
- Deepgram.Microphone/Microphone.cs (3 hunks)
- Deepgram/Clients/Interfaces/v1/Constants.cs (1 hunks)
- Deepgram/Clients/Interfaces/v1/IListenWebSocketClient.cs (1 hunks)
- Deepgram/Clients/Interfaces/v1/ISpeakWebSocketClient.cs (3 hunks)
- Deepgram/Clients/Listen/v1/WebSocket/Client.cs (1 hunks)
- Deepgram/Clients/Listen/v1/WebSocket/Constants.cs (1 hunks)
- Deepgram/Clients/Listen/v1/WebSocket/WebSocketMessage.cs (1 hunks)
- Deepgram/Clients/Speak/v1/WebSocket/Client.cs (5 hunks)
- Deepgram/Clients/Speak/v1/WebSocket/Constants.cs (1 hunks)
- Deepgram/Clients/Speak/v1/WebSocket/WebSocketMessage.cs (1 hunks)
🔇 Additional comments not posted (13)
Deepgram/Clients/Interfaces/v1/Constants.cs (2)
1-3
: LGTM: Copyright and licensing information is correct.The copyright notice, license specification, and SPDX identifier are all present and correctly formatted.
5-5
: LGTM: Namespace declaration is correct.The namespace
Deepgram.Clients.Interfaces.v1
follows the expected structure for the Deepgram .NET SDK.Deepgram/Clients/Listen/v1/WebSocket/Constants.cs (1)
Line range hint
1-24
: Overall changes look good.The additions to the
Constants
class are well-structured and align with the PR objectives. They enhance the configurability of the SDK without introducing any apparent issues. The consistent naming conventions and focused changes contribute to maintaining code quality.Deepgram.Microphone/Microphone.cs (2)
14-14
: LGTM: Improved callback signatureThe change in the
_push_callback
field type fromAction<byte[]>
toAction<byte[], int>
is a good improvement. It allows for passing both the byte array and its length to the callback, which can provide more flexibility and potentially better performance by avoiding unnecessary length calculations. This change aligns well with the PR objectives of implementing length parameters on send functions.
Line range hint
1-180
: Summary: Successful implementation of length parameter in callbackThe changes made to the
Microphone
class successfully implement the length parameter in the callback function, as outlined in the PR objectives. The modifications to the_push_callback
field, constructor signature, and_callback
method are consistent and well-implemented.These changes provide more flexibility and potentially better performance by allowing direct access to the buffer length without recalculation. The implementation aligns well with the goal of exposing more detailed information about the audio data being processed.
Overall, the changes are approved with minor suggestions for documentation updates and optimization.
Deepgram/Clients/Interfaces/v1/IListenWebSocketClient.cs (6)
74-77
: LGTM: SendKeepAlive method addedThe
SendKeepAlive
method is a good addition to the interface. It provides a clear way to send keep-alive messages, which can be crucial for maintaining long-lived WebSocket connections.
79-82
: LGTM: SendFinalize method addedThe
SendFinalize
method is a valuable addition to the interface. It provides a clear way to send finalization messages, which can be important for properly ending WebSocket sessions or data streams.
84-87
: LGTM: SendClose method added, but clarification neededThe
SendClose
method is a good addition to the interface, providing a clear way to initiate the closing of a WebSocket connection. However, the purpose of thenullByte
parameter is not immediately clear.Could you please add a comment explaining the purpose and effect of the
nullByte
parameter? This will help users of the interface understand when they might want to set it to true.
109-109
: LGTM: Length parameter added to immediate Send methodsThe addition of the
length
parameter toSendBinaryImmediately
andSendMessageImmediately
methods is consistent with the changes made to the other send methods. This provides the same flexibility for controlling the amount of data sent in immediate mode.Also applies to: 114-114
Line range hint
1-114
: Overall assessment: Positive improvements to IListenWebSocketClient interfaceThe changes made to the
IListenWebSocketClient
interface are well-structured and consistent. They achieve the stated objectives of the PR by:
- Implementing length parameters on send functions, which provides more flexibility in controlling data transmission.
- Exposing new functionalities through the addition of
SendKeepAlive
,SendFinalize
, andSendClose
methods.These modifications enhance the capabilities of the WebSocket client while maintaining backward compatibility through the use of optional parameters. The changes align well with the goals of improving the functionality and usability of the Deepgram .NET SDK.
93-93
: LGTM: Length parameter added to Send methodsThe addition of the
length
parameter toSend
,SendBinary
, andSendMessage
methods provides more flexibility in controlling the amount of data sent. This is a good improvement that allows for partial sends of byte arrays.Please ensure that
Constants.UseArrayLengthForSend
is properly defined in theConstants
class. You can verify this by running the following command:Also applies to: 99-99, 104-104
✅ Verification successful
Please run the following script to locate the definition of
UseArrayLengthForSend
across the entire codebase:
Default length handling in constructors is consistent
All instances of
Constants.UseArrayLengthForSend
are consistently defined as-1
across the codebase, and its usage is clear throughout.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the usage and value of Constants.UseArrayLengthForSend. # Test: Search for the definition and usages of UseArrayLengthForSend. rg --type cs "UseArrayLengthForSend" # Display the value assigned to UseArrayLengthForSend. rg --type cs "public\s+const\s+int\s+UseArrayLengthForSend\s*=\s*-1;"Length of output: 3799
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (10)
- Deepgram.Microphone/Microphone.cs (3 hunks)
- Deepgram/Clients/Interfaces/v1/Constants.cs (1 hunks)
- Deepgram/Clients/Interfaces/v1/IListenWebSocketClient.cs (1 hunks)
- Deepgram/Clients/Interfaces/v1/ISpeakWebSocketClient.cs (3 hunks)
- Deepgram/Clients/Listen/v1/WebSocket/Client.cs (1 hunks)
- Deepgram/Clients/Listen/v1/WebSocket/Constants.cs (1 hunks)
- Deepgram/Clients/Listen/v1/WebSocket/WebSocketMessage.cs (1 hunks)
- Deepgram/Clients/Speak/v1/WebSocket/Client.cs (5 hunks)
- Deepgram/Clients/Speak/v1/WebSocket/Constants.cs (1 hunks)
- Deepgram/Clients/Speak/v1/WebSocket/WebSocketMessage.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
- Deepgram.Microphone/Microphone.cs
- Deepgram/Clients/Interfaces/v1/Constants.cs
- Deepgram/Clients/Interfaces/v1/IListenWebSocketClient.cs
- Deepgram/Clients/Interfaces/v1/ISpeakWebSocketClient.cs
- Deepgram/Clients/Listen/v1/WebSocket/Client.cs
- Deepgram/Clients/Listen/v1/WebSocket/Constants.cs
- Deepgram/Clients/Speak/v1/WebSocket/Client.cs
- Deepgram/Clients/Speak/v1/WebSocket/Constants.cs
- Deepgram/Clients/Speak/v1/WebSocket/WebSocketMessage.cs
🔇 Additional comments not posted (3)
Deepgram/Clients/Listen/v1/WebSocket/WebSocketMessage.cs (3)
7-7
: LGTM: Good use ofreadonly
andinternal
modifiers.The
readonly
modifier ensures immutability, which is a good practice for structs. Theinternal
access modifier is appropriate for this utility struct, limiting its visibility to the assembly.
9-12
: LGTM: Good use of constructor chaining for backward compatibility.This constructor maintains backward compatibility while leveraging the new functionality. The use of
Constants.UseArrayLengthForSend
as a default value ensures consistency throughout the codebase.
28-32
: LGTM: Properties are well-defined and consistent with the struct's purpose.The properties
Length
,Message
, andMessageType
are correctly implemented as auto-properties. They are implicitly read-only due to thereadonly
struct modifier, which ensures immutability. The addition of theLength
property is consistent with the constructor changes.
public WebSocketMessage(byte[] message, WebSocketMessageType type, int length) | ||
{ | ||
if (length != Constants.UseArrayLengthForSend || length < Constants.UseArrayLengthForSend) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of the || condition? If length is < -1, then it is a negative number, what does it mean to pass a negative number to ArraySegment? Perhaps you meant the following instead?
if (length != Constants.UseArrayLengthForSend && length <= message.Length) // ensure provided length is valid
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you pass a negative number (which is invalid), it just takes the length of the buffer. We could also throw an exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But a negative length will go into the top half of the if and will be passed to ArraySegment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems the following would be best:
if (length != Constants.UseArrayLengthForSend && length <= message.Length && length > 0) // if length is provided ensure it is valid
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point. will make an update for more bumper rails in a follow up PR. In the meantime, I hope that someone would not put in a negative length.
Proposed changes
Addresses: #333, #332
Just like the title says....
Tested STT Microphone example and works as expected.
Types of changes
What types of changes does your code introduce to the community .NET SDK?
Put an
x
in the boxes that applyChecklist
Put an
x
in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.Further comments
NA
Summary by CodeRabbit
Release Notes
New Features
SendClose
method to facilitate closing streams with optional parameters.Improvements
WebSocketMessage
struct to support variable-length messages.Microphone
class to improve callback handling for data processing.Bug Fixes