graceful-fs was added at a time when channel state was stored in
flatfiles that could become corrupted if enough concurrent saves
occurred to hit the ulimit for maxfds (EMFILE). Saving channels this
way is no longer supported, so it shouldn't be an issue anymore.
This reverts commit d678fa56d1. The
reference counter, flawed as it is, was masking far more issues than I
realized. It would require a more significant rearchitecture of the
code to remove it. Probably better to keep it and try to improve it for
now.
This was an old attempt at gracefully unloading channels that still had
pending callbacks. Its implementation was always flawed, and the number
of places where it was used is small enough to replace with
straightforward checks for whether the channel has been unloaded after
an asynchronous operation. Hopefully fixes the stuck 0 user channels
issue.
Unfortunately I think this is just one of a whole class of race
conditions caused by errored channels being unloaded immediately without
waiting for the refcounter to reach 0.
However, this one is the only one that appears commonly in the logs so
adding this check should buy time to rethink the overall problem.
Fixes#681. Technically, resending the entire userlist is not
necessary; it would be sufficient to resent setUserMeta, but there's not
currently a bulk frame for that so sending the userlist is probably more
efficient.
User.prototype.refreshAccount was responsible for multiple race
condition bugs as well as inefficient duplication of DB queries in an
attempt to correct such race conditions.
It has now been replaced by a more reasonable model:
* Global user account information and aliases are fetched in parallel
on socket connection
* Channel rank is fetched when the user tries to join a channel
The previous commits do not handle all of the edge cases of #583
appropriately. This is a short term solution that will work, but is not
as efficient as it could be. The whole refreshAccount function needs to
be reconsidered and replaced with a more sane way of handling atomic
updates to the user's account state.
Instead of emitting frames to each individual socket, group them into
socket.io rooms of people who can see hidden poll results and people who
can't, then just do 2 broadcasts.
CyTube has been crashing recently due to things attempting to release
the reference after the channel was already closed (apparently the
uncaughtException handler isn't called for this?). This newer
implementation keeps track of what is ref'ing and unref'ing it, so it
can log an error if it detects a discrepancy.
Also changed the server to not delete the refCounter field from the
channel when it's unloaded, so that should reduce the number of errors
stemming from it being null/undefined.