Register subscription doc under doc_id key rather than field_key #1268
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We've been running some performance tests against Absinthe subscriptions and discovered a curious scenario: if large number of clients were disconnecting at the same time, the app would become unresponsive and remain in this state until ETS memory consumption caused by the test did not drop to normal levels. And that was taking a lot of time.
After further investigation we were able to narrow down the following scenario:
compress_registry?
settings totrue
.What happens next is that Registry begins to cleanup data associated with Absinthe channel processes using ets
match_delete
call. And since the table is compressed, it has to uncompress values to run match against them, which turned out to be a slow enough operation to occupy all cpu cores and starve other processes. Registry is smart enough to scope this operation by key, but the problem is that Absinthe stores subscription data underfield_key
which is shared between subscriptions, so the scoping doesn't help.The solution I came up in this PR is to split data which Absinthe puts in Registry from
{field_key, {doc_id, doc}}
into 2 records:{field_key, doc_id}
and{doc_id, doc}
. This way total amount of data stored under sharedfield_key
should be much smaller and thus quicker to traverse.