|
|
|
|
|
by mrkeen
376 days ago
|
|
I did a fair bit of Rust (only single-threaded, quite a few years ago) but it sounds like the dependency inversion principle is popping up again. DIP, async/await, coloured-functions, io-monad. All cases where the business logic should go in one column (abstract/sync/blue/pure), and your machinery should go in the other column (concrete/async/red/io). Your logic will remain unit-testable that way, regardless of how big or small it gets. Irritated newcomers will complain about not being able to call in the other direction. So what's a language-designer to do? Attract the largest possible user-base by not getting in the user's way - or filter out frustrated users and have fewer but better codebases out there? |
|
The typical pattern I enjoy is:
* Sync for the logic
* Async for the job runners b/c I'd like to do other things while it's going.
* Sync or Async as required for the data wrangling (db calls, network, filesystem)
So you have essentially:
1. kick off job, returning a future, by calling an async function.
2. Job is mostly async data wrangling, followed by a sync logic block that's unit tested, followed by an async "save" if required.
3. Either wait for the future, or run the task in the background, or `.await` if you're in an async block.
I'm hand waving away the syntax, but that's the mental model. 99% of code isn't async, and the code that is isn't async for the fun of it.