When `write` is called on a `StreamTransport`, the current sequence of
operations is:
* copy data to queue
* register for "write" event notification
* return unfinished future to `write` caller
* wait for "write" notification (in `poll`)
* perform one `send`
* wait for notification again if there's more data to write
* complete the future
In this PR, we introduce a fast path for writing:
* If the queue is empty, try to send as much data as possible
* If all data is sent, return completed future without `poll` round
* If there's more data to send than can be sent in one go, add the
rest to queue
* If the queue is not empty, enqueue as above
* When notified that write is possible, keep writing until OS buffer is
full before waiting for event again
The fast path provides significant performance benefits when there are
many small writes, such as when sending gossip to many peers, by
avoiding the poll loop and data copy on each send.
Also fixes an issue where the socket would not be removed from the
writer set if there were pending writes on close.
* Add more accept() call error handlers.
Fix issue when HTTP server silently stops accepting new connections.
Remove unneeded MacOS syscall to disable SIG_PIPE on socket, we already mask this signal in process.
* User `if` instead `case` because constants are actually variables.
* Fix mistypes.
* Do not use case for posix constants.
* Fix Linux compilation error.
* Change Future identifier type from `int` to `uint64`.
* Fix compilation error and tests.
* Add integer overflow test, to avoid confusion with next Nim versions, we expect that unsigned integers do not raise any exceptions if overflow happens.
* Switch from `uint64` to `uint` type.
* Add `uint` overflow tests.
Fix async streams issue with replacing state.
Add `closing` states to HTTP's server connection, request and bodyrw.
Fix Http server cancellation leaks.
* Initial commit.
* Some refactoring.
* Allow boundstream to accept uint64.
Fix httpserver and asyncstream tests to follow new uint64 requirement.
* send() and getBodyBytes() implementations.
* Add closeWait for response and request.
Refactor finish/close flow.
* Changes in state machine
Add first test.
* Missing test file.
* Fixed tests
Add http leaking trackers and tests.
* Some fixes in multipart.
Fix automatic Content-Length header for requests with body.
Fix getBodyBytes() assertions.
Merging tests to main suite.
* Post rebase fixes.
* Fix tests big message generation.
* Fix response state management and leaks for getBodyXXX() procedures.
* Add redirection support to client and server.
Add fetch(url) procedure with redirection support.
Add tests for redirection.
* Restore functionality of zero-sized bounded reader/writer streams.
Adding tests for it.
* run build_nim.sh unconditionally
Co-authored-by: Ștefan Talpalaru <stefantalpalaru@yahoo.com>
* Refactor common.nim to remove `result` usage.
Fix comparison of TransportAddress issue.
Add resolveTAddress procedures for both IPv4 and IPv6 addresses.
Fix tests.
* Bump version to 3.0.2.
* exception tracking
This PR adds minimal exception tracking to chronos, moving the goalpost
one step further.
In particular, it becomes invalid to raise exceptions from `callSoon`
callbacks: this is critical for writing correct error handling because
there's no reasonable way that a user of chronos can possibly _reason_
about exceptions coming out of there: the event loop will be in an
indeterminite state when the loop is executing an _random_ callback.
As expected, there are several issues in the error handling of chronos:
in particular, it will end up in an inconsistent internal state whenever
the selector loop operations fail, because the internal state update
functions are not written in an exception-safe way. This PR turns this
into a Defect, which probably is not the optimal way of handling things
- expect more work to be done here.
Some API have no way of reporting back errors to callers - for example,
when something fails in the accept loop, there's not much it can do, and
no way to report it back to the user of the API - this has been fixed
with the new accept flow - the old one should be deprecated.
Finally, there is information loss in the API: in composite operations
like `poll` and `waitFor` there's no way to differentiate internal
errors from user-level errors originating from callbacks.
* store `CatchableError` in future
* annotate proc's with correct raises information
* `selectors2` to avoid non-CatchableError IOSelectorsException
* `$` should never raise
* remove unnecessary gcsafe annotations
* fix exceptions leaking out of timer waits
* fix some imports
* functions must signal raising the union of all exceptions across all
platforms to enable cross-platform code
* switch to unittest2
* add `selectors2` which supercedes the std library version and fixes
several exception handling issues in there
* fixes
* docs, platform-independent eh specifiers for some functions
* add feature flag for strict exception mode
also bump version to 3.0.0 - _most_ existing code should be compatible
with this version of exception handling but some things might need
fixing - callbacks, existing raises specifications etc.
* fix AsyncCheck for non-void T
1. Implement all read() primitives using readLoop() like it was done in streams.
2. Fix readLine() bug.
3. Add readMessage() primitive.
4. Fixing exception hierarchy, handling code and simplification of (break/continue + exception).
5. Fix TLSStream closure procedure.
6. Add BoundedStream stream and tests.
7. Remove `result` usage from the code.
IPV6_MULTICAST_HOPS already declared in posix.nim while IP_MULTICAST_TTL
has a value that will stay constant on linux/x86_64 - better codegen and
nlvm compat like this.
* Add callIdle primitive.
* Make single idle callback to be processed by single poll() step.
Add idleAsync() primitive to allow wait for "idle" time.
Refactor some `result` usage.
it seems that due to a naming conflict from asyncdispatch, callSoon is
deduced to raise exceptions even if it doesn't in modules that import
both, even indirectly - this patch randomly works around the issue with
some more overloads
* Fix cancellation behavior.
Fix some compilation warnings.
* Fix cancelAndWait() and add proper documentation.
* Add completed(Future) and done(Future) calls to check if Future[T] completed without an error.
* Add stepsAsync() and tests.
* Fix comments.
* Fix new primitive comment, to avoid usage for task switches.
* release callback memory early
this fixes a memory leak where a deleted callback may keep references
alive until the future is finished.
In particular, when using helpers like `or` which try to remove
themselves from the callback list when a dependent future is completed,
create a reference chain between all futures in the expression - in the
pathological case where one of the futures is completes only rarely (for
example a timeout or a cancellation task), the buildup will be
significant.
* Removing unnecessary asserts, and place comments instead.
* Fix `locked` flag to be more consistent.
Refactor AsyncLock to not use `result`.
Add test for `locked` flag.
* Fixes.
* Fix imports.
* Fix multiple release() without scheduler.
Add more tests.
* Fix review comments.
* small fixes
* more efficient codegen for nil check (much less code)
* release futures earlier in AsyncEvent
* release finished future earlier in AsyncQueue
* avoid searches for futures (deque variant unused / broken)
* avoid catching defects
* Fix AsyncEvent test, because of optimization.
* delete fix
* avoid seq allocs
* Keep style consistent with other code.
Refactor AsyncEvent and AsyncQueue to not use `result` keyword.
Co-authored-by: cheatfate <eugene.kabanov@status.im>
This reverts commit e45ef32b5b.
Metrics implemented this way, with a lock inside the otherwise tight
event loop are not consistent with the chronos architecture that for
good or bad uses thread local variables to avoid them - the solution
does not have rough consensus behind it, and other avenues should be
explored for this generally useful functionality.
This reverts commit d0a17d551f.
Moving CancelledError outside of the established Nim hierarchy is
not a solution that has rough consensus and has an unknown impact
on compatibility with otherwise correctly implemented cancellation
code (for example when `CatchableError` is caught, cleanup is done,
then the exception is reraised). Further, this breaks the established
convention in the Nim community that Exception should not be inherited
from, complicating compatibility with future Nim versions that may
enforce this more strongly.
This reverts commit 284d677815.
There is no rough consensus for how this should be implemented and
whether it's needed indeed - a use case that cannot be solved with
a queue or a lock/event should be identified before pursuing this
functionality.
This reverts commit baf33f04ea.
This change hides exceptions that should be handled explicitly -
asyncCheck is a debugging tool that should only be used in
exception-free situations (indeed, to fail when the operation
unexpectedly raises). There is no rough consensus behind this
change.
The cancellation process has a very complicated control flow, split over
different files and hidden by macros. These comments should help shed a
light on this madness.
* Make Future tracking optional via -d:chronosDutureTracking compilation flag.
* Stack traces is now optional, use -d:chronosStackTraces.
* Fix mistypes and add test for chronosStackTrace option.