Commit Graph

7 Commits

Author SHA1 Message Date
Jacek Sieka f03cdfcc40
futures: sinkify (#475)
This avoids copies here and there throughout the pipeline - ie
`copyString` and friends can often be avoided when moving things into
and out of futures

Annoyingly, one has to sprinkle the codebase liberally with `sink` and
`move` for the pipeline to work well - sink stuff _generally_ works
better in orc/arc

Looking at nim 1.6/refc, sink + local variable + move generates the best
code:

msg directly:
```nim
	T1_ = (*colonenv_).msg1; (*colonenv_).msg1 = copyStringRC1(msg);
```

local copy without move:
```nim
	T60_ = (*colonenv_).localCopy1; (*colonenv_).localCopy1 =
copyStringRC1(msg);
```

local copy with move:
```nim
	asgnRef((void**) (&(*colonenv_).localCopy1), msg);
```

Annoyingly, sink is also broken for refc+literals as it tries to
changes the refcount of the literal as part of the move (which shouldn't
be happening, but here we are), so we have to use a hack to find
literals and avoid moving them.
2023-11-19 18:29:09 +01:00
Jacek Sieka 1306170255
dedicated exceptions for `Future.read` failures (#474)
Dedicated exceptions for `read` failures reduce the risk of mixing up
"user" exceptions with those of Future itself. The risk still exists, if
the user allows a chronos exception to bubble up explicitly.

Because `await` structurally guarantees that the Future is not `pending`
at the time of `read`, it does not raise this new exception.

* introduce `FuturePendingError` and `FutureCompletedError` when
`read`:ing a future of uncertain state
* fix `waitFor` / `read` to return `lent` values
* simplify code generation for `void`-returning async procs
* document `Raising` type helper
2023-11-17 13:45:17 +01:00
Jacek Sieka f5ff9e32ca
introduce asyncraises in transports/asyncsync (#470)
With these fixes, `transports`/`asyncsync` correctly propagate and document their raises information - generally, most transport functions (send etc) raise `TransportError` and `CancelledError` - `closeWait` is special in that it generally doesn't fail.

This PR introduces the syntax `Future[void].Raises([types])` to create the `InternalRaisesFuture` type with the correct encoding for the types - this allows it to be used in user code while retaining the possibility to change the internal representation down the line.

* introduce raising constraints on stream callbacks - these constraints now give a warning when called with a callback that can raise exceptions (raising callbacks would crash 
* fix fail and its tests, which wasn't always given a good generic match
* work around nim bugs related to macro expansion of generic types
* make sure transports raise only `TransportError`-derived exceptions (and `CancelledError`)
2023-11-15 09:38:48 +01:00
Jacek Sieka 5ebd771d35
per-function `Exception` handling (#457)
This PR replaces the global strict exception mode with an option to
handle `Exception` per function while at the same time enabling strict
exception checking globally by default as has been planned for v4.

`handleException` mode raises `AsyncExceptionError` to distinguish it
from `ValueError` which may originate from user code.

* remove obsolete 1.2 config options
2023-11-08 15:12:32 +01:00
Jacek Sieka cd6369c048
`asyncraises` -> `async: (raises: ..., raw: ...)` (#455)
Per discussion in
https://github.com/status-im/nim-chronos/pull/251#issuecomment-1559233139,
`async: (parameters..)` is introduced as a way to customize the async
transformation instead of relying on separate keywords (like
asyncraises).

Two parameters are available as of now:

`raises`: controls the exception effect tracking
`raw`: disables body transformation

Parameters are added to `async` as a tuple allowing more params to be
added easily in the future:
```nim:
proc f() {.async: (name: value, ...).}`
```
2023-11-07 12:12:59 +02:00
Jacek Sieka f56d286687
introduce `asyncraises` to core future utilities (#454)
* introduce `asyncraises` to core future utilities

Similar to the introduction of `raises` into a codebase, `asyncraises`
needs to be introduced gradually across all functionality before
deriving benefit.

This is a first introduction along with utilities to manage raises lists
and transform them at compile time.

Several scenarios ensue:

* for trivial cases, adding `asyncraises` is enough and the framework
deduces the rest
* some functions "add" new asyncraises (similar to what `raise` does in
"normal" code) - for example `wait` may raise all exceptions of the
future passed to it and additionally a few of its own - this requires
extending the raises list
* som functions "remove" raises (similar to what `try/except` does) such
as `nocancel` with blocks cancellations and therefore reduce the raising
set

Both of the above cases are currently handled by a macro, but depending
on the situation lead to code organisation issues around return types
and pragma limitations - in particular, to keep `asyncraises`
backwards-compatibility, some code needs to exist in two versions which
somewhat complicates the implementation.

* add `asyncraises` versions for several `asyncfutures` utilities
* when assigning exceptions to a `Future` via `fail`, check at compile
time if possible and at runtime if not that the exception matches
constraints
* fix `waitFor` comments
* move async raises to separate module, implement `or`
2023-10-24 16:21:07 +02:00
Jacek Sieka e3c5a86a14
Introduce chronos/internals, move some code (#453)
* Introduce chronos/internals, move some code

This PR breaks the include dependencies between `asyncfutures2` and
`asyncmacros2` by moving the dispatcher and some other code to a new
module.

This step makes it easier to implement `asyncraises` support for future
utilities like `allFutures` etc avoiding the need to play tricks with
include order etc.

Future PR:s may further articulate the difference between "internal"
stuff subject to API breakage and regular public API intended for end
users (rather than advanced integrators).

* names

* windows fix
2023-10-17 20:25:25 +02:00