Skip to content
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

Expose MaxPendingBytes on the natsOptions #700

Merged
merged 9 commits into from
Apr 5, 2024

Conversation

LaurensVergote
Copy link
Contributor

@LaurensVergote LaurensVergote commented Nov 27, 2023

Similar as https://github.com/nats-io/nats.net/pull/844 from the nats.net library.
I've used the same defaults as the C# library

Couldn't get the testsuite to work locally so I hope the github pipeline will run them :)

Copy link
Member

@kozlovic kozlovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, thank you for the contribution. But I am afraid that this could break applications the way it is coded. Review my comments. You missed a step to regenerate the test/list.txt, this is why you were not able to run the tests (and CI did not either).
Finally, since this is added a new API (and unless @levb no longer plans on using the dev branch), this PR should have been made against the dev branch.

src/natsp.h Outdated
@@ -265,6 +265,7 @@ struct __natsOptions
int64_t pingInterval;
int maxPingsOut;
int maxPendingMsgs;
long maxPendingBytes;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this an int64_t (although could arguably made an uint64_t, but in case we want to use negative value to mean something).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

src/opts.c Outdated
@@ -883,6 +883,18 @@ natsOptions_SetMaxPendingMsgs(natsOptions *opts, int maxPending)
return NATS_OK;
}

natsStatus
natsOptions_SetMaxPendingBytes(natsOptions* opts, long maxPending)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int64_t

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

src/sub.c Outdated
@@ -454,7 +450,7 @@ natsSub_create(natsSubscription **newSub, natsConnection *nc, const char *subj,
sub->msgCb = cb;
sub->msgCbClosure = cbClosure;
sub->msgsLimit = nc->opts->maxPendingMsgs;
sub->bytesLimit = bytesLimit;
sub->bytesLimit = nc->opts->maxPendingBytes;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we are changing behavior here. If the user set the option of maxPendingMsgs, we would set the limit to that value * 1024 (by default). Now it would be the default value that you have set to 64MB. In other words, that could break applications.
I would suggest that we don't set a default then, and so, if <=0, we multiply the maxPendingMsgs by 1024, otherwise, we use the set value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked for NATS_OPTS_DEFAULT_MAX_PENDING_BYTES equality instead of not setting a default.

@@ -2580,6 +2580,7 @@ test_natsOptions(void)
&& (opts->maxPingsOut == 2)
&& (opts->ioBufSize == 32 * 1024)
&& (opts->maxPendingMsgs == 65536)
&& (opts->maxPendingBytes == 67108864)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not, see comment above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be valid with reviewed implementation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would not be if you agree with my earlier comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

test/test.c Show resolved Hide resolved
test/test.c Outdated Show resolved Hide resolved
test/test.c Outdated Show resolved Hide resolved
test/test.c Show resolved Hide resolved
test/test.c Outdated Show resolved Hide resolved
test/test.c Outdated Show resolved Hide resolved
@LaurensVergote
Copy link
Contributor Author

Not quite sure why the CI timed out on one of the new tests, had no issues locally running it

src/sub.c Outdated
@@ -454,7 +451,7 @@ natsSub_create(natsSubscription **newSub, natsConnection *nc, const char *subj,
sub->msgCb = cb;
sub->msgCbClosure = cbClosure;
sub->msgsLimit = nc->opts->maxPendingMsgs;
sub->bytesLimit = bytesLimit;
sub->bytesLimit = nc->opts->maxPendingBytes == NATS_OPTS_DEFAULT_MAX_PENDING_BYTES ? nc->opts->maxPendingMsgs * 1024 : nc->opts->maxPendingBytes;;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. Because if the user happens to want to set the limit to 64MB, then the actual limit would be whatever maxPendingMsgs*1024 is. This is incorrect. So what I was suggesting is either we make it a breaking change (and since it is a new API it should only go in 3.8.0 anyway), or we initialize the value to -1, so that we can detect here that it was not user-set, and if that is the case, then use the "old" formula (pendingMsgs * 1024) or if set use the provided value. So there would not be a need for the new NATS_OPTS_DEFAULT_MAX_PENDING_BYTES constant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -2580,6 +2580,7 @@ test_natsOptions(void)
&& (opts->maxPingsOut == 2)
&& (opts->ioBufSize == 32 * 1024)
&& (opts->maxPendingMsgs == 65536)
&& (opts->maxPendingBytes == 67108864)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would not be if you agree with my earlier comment.

size_t data_len = 10;
const char msg[] = { 0,1,2,3,4,5,6,7,8,9 }; //10 bytes long message

for (int i = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For code consistency. It came from a time where - I believe on Windows, with whatever compiler version we were using - it was not possible to declare variables there. We could relax that, especially in test.c, but I like to keep things consistent. It also help prevent variable shadowing bugs.

@@ -14345,7 +14350,7 @@ _asyncErrCb(natsConnection *nc, natsSubscription *sub, natsStatus err, void* clo
}

static void
test_AsyncErrHandler(void)
test_AsyncErrHandler_MaxPendingMsgs(void)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the issue is in _asyncErrCb (I know it is not related to your change). Could you please make the following change?

diff --git a/test/test.c b/test/test.c
index 2c164b7f..59f9824d 100644
--- a/test/test.c
+++ b/test/test.c
@@ -14344,7 +14344,7 @@ _asyncErrCb(natsConnection *nc, natsSubscription *sub, natsStatus err, void* clo
 
     arg->closed = true;
     arg->done = true;
-    natsCondition_Signal(arg->c);
+    natsCondition_Broadcast(arg->c);
 
     natsMutex_Unlock(arg->m);
 }

The issue is that the subscription's callback is waiting for closed to be set to true and waits on the condition variable. Since both the test and the callback wait on the async error callback notification, there is a chance that the signal leaves the callback blocked. Doing the broadcast should solve that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

@kozlovic kozlovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's fix the for loop to not have the warning. But more importantly, we need @levb to confirm if we are still using the dev branch for new features. If so, this PR will need to change the base branch from main to dev. As of now though, I don't think that dev is up-to-date, so let's wait on @levb to confirm what we need to do here.

size_t data_len = 10;
const char msg[] = { 0,1,2,3,4,5,6,7,8,9 }; //10 bytes long message

for (int i = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That produces warnings:

[ 98%] Building C object test/CMakeFiles/testsuite.dir/test.c.o
/home/travis/build/nats-io/nats.c/test/test.c: In function ‘test_AsyncErrHandler_MaxPendingBytes’:
/home/travis/build/nats-io/nats.c/test/test.c:14453:5: warning: statement with no effect [-Wunused-value]
14453 |     for (i;
      |     ^~~

Instead, do for (i=0; ....

test/test.c Outdated
natsMutex_Unlock(arg.m);

test("Cause an error by sending too many messages: ");
for (i;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment than in the other test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

@kozlovic kozlovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Will let @levb have a look and merge if he is ok with it.

Copy link
Collaborator

@levb levb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@levb levb merged commit ff8528f into nats-io:main Apr 5, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants