-
Notifications
You must be signed in to change notification settings - Fork 380
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
cache: Poll dying connection pools asynchronously #4198
base: master
Are you sure you want to change the base?
Conversation
@cartoush IIRC your commit messages and pull requests so far all were extremely terse. Can you please elaborate such that reviewers can easily understand which problem you are trying to solve, why you chose a particular approach and, if necessary, how you implemented it? I recently noticed a guide which I would be tempted to propose to adopt for our project: https://github.com/axboe/liburing/blob/master/CONTRIBUTING.md |
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.
There is room for improvement but this is a good start!
b036a10
to
3e810ad
Compare
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.
LGTM, with nitpicks.
3e810ad
to
2ed8719
Compare
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 just realized splitting this operation brings it in two different contexts, see comments. I have not thought much about how to proceed so my questions are open questions.
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.
As pointed out by others, locking is not correct yet.
I think we should just have a single lock for dead_pools
, and insert each dead cp under that lock.
VCP_RelPoll (if we keep it like this) can just swap the list head under that mtx, work all entries unlocked, remembering those still active (n_kill > 0
) on a new list, and finally appending the new list back to dead_pools
under the mtx.
Alternatively, why do we not just hand dead pool handling to a worker thread?
edit: this facility has a mascot
I guess we could work with a mutex dedicated to the dead pools and not even care about the per-vcp lock. Since we care about observing
Isn't a CLI hook good-enough for this kind of cleanup sweep? |
2ed8719
to
f33a8ff
Compare
6e5f482
to
d1fae69
Compare
It probably is, but I do not know, this was just an option to maybe consider. I would really like to see swapping the tree head and working the cleanup outside any connection pool mtx. |
d1fae69
to
1b9e6cc
Compare
Added a |
1b9e6cc
to
94dc91d
Compare
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 think I'm OK with this now, but I'm running out of brain cycles.
94dc91d
to
dce32c9
Compare
dce32c9
to
e02dc00
Compare
e02dc00
to
a67abc0
Compare
calls to |
a67abc0
to
233b57a
Compare
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.
Reconciling the desire to loop without holding the lock with the reuse of the VRBT_ENTRY()
field already present in struct conn_pool
is complicating the change above my acceptable threshold.
If we put the cursor on the lock, then we should probably have a tail queue of dead connections as suggested before. We keep constant-time operations, including the ability to easily steal and reinject dead pools before and after the cleanup loop.
@nigoroll thoughts?
bin/varnishd/cache/cache_conn_pool.c
Outdated
Lck_Unlock(&dead_pools_mtx); | ||
return; | ||
} | ||
TAKE_OBJ_NOTNULL(dead.rbh_root, &dead_pools.rbh_root, CONN_POOL_MAGIC); |
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 don't think you can safely do that, it should look something like this instead:
dead = dead_pools;
VRBT_INIT(&dead_pools);
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.
Yeah, the TAKE_OBJ
is a smart idea, but using the tree macros as intended would be my preference also.
bin/varnishd/cache/cache_conn_pool.c
Outdated
if (!VRBT_EMPTY(&dead)) { | ||
Lck_Lock(&dead_pools_mtx); | ||
VRBT_INSERT(vrb, &dead_pools, dead.rbh_root); | ||
Lck_Unlock(&dead_pools_mtx); | ||
} |
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.
VRBT_INSERT()
inserts a single entry, not another tree, or does it?
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.
From what I understood a single entry is a tree with only 1 element, so inserting the root of a tree should insert the whole tree but I could be wrong
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.
this is actually pretty smart, IMHO, and I did not think of it: I originally thought we would iterate the leftovers and insert one by one, but as we do not care about ordering in the dead_pools
tree, this should work.
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 checked the tree macros and indeed, the comparison function is only used for insert and lookup (as expected). So yeah, I think this is still nicer than the alternative of using a union with list pointers in place of the tree pointers.
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 wasn't suggesting a union, but if this is safe but "incorrect", we should add red tape to remind our future selves why this is good enough.
Except for the one or two nitpicks, I like the structure of the patch now. I do not understand which complication @dridi is seeing, IMHO, this is a simplification. |
That was in the optic of not misusing the VRBT API on purpose. I'll comment in that thread. |
8366423
to
ed7d2d8
Compare
Fixed comments and added comments to the |
ed7d2d8
to
274d4ce
Compare
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.
Good job!
Before, we would wait in a blocking loop for connection pools to be freed before deleting them for good. This commit transforms this blocking loop into a CLI hook that will delete the freed connection pools at each trigger. Refs varnishcache#4064 Better diff with the --ignore-all-space option.
274d4ce
to
ec73181
Compare
@bsdphk two people think this one is ripe |
This PR moves the blocking sleep loop to a CLI hook.
See #4064