Closes #56. This PR runs the websocket I/O on a separate thread, instead of polling using later(). When a WebSocket exists but is idle, in a terminal it previously consumed about 2.5% CPU on my computer, and in RStudio it previously consumed 0.7%. Now it consumes 0% because the I/O thread's event loop works without using polling (I believe it uses something like epoll or select under the hood).
[x] Document that if even you lose the reference to an open WebSocket object, it will continue to exist until the websocket is closed; after that point, a gc() will GC it.
[x] Update existing tests for new non-polling behavior.
[x] Add test that if ref to ws is gone, and the websocket is closed from the other end, that a gc() will cause the finalizer to run.
[x] Add test for running in private loop.
[x] Add test that a failed connection gets finalized, even without a close()
[x] Add substitutes for Rcerr and Rcout that are safe to run on background thread.
Closes #56. This PR runs the websocket I/O on a separate thread, instead of polling using
later()
. When a WebSocket exists but is idle, in a terminal it previously consumed about 2.5% CPU on my computer, and in RStudio it previously consumed 0.7%. Now it consumes 0% because the I/O thread's event loop works without using polling (I believe it uses something likeepoll
orselect
under the hood).Also, with Chromote, it previously idled at ~6.5% CPU, but after this change and https://github.com/rstudio/chromote/pull/16, it idles at 0%.
TODO:
gc()
will GC it.ws
is gone, and the websocket is closed from the other end, that agc()
will cause the finalizer to run.close()
Rcerr
andRcout
that are safe to run on background thread.