planety / prologue

Powerful and flexible web framework written in Nim
https://planety.github.io/prologue
Apache License 2.0
1.24k stars 47 forks source link

Chronos support #247

Open thatrandomperson5 opened 6 hours ago

thatrandomperson5 commented 6 hours ago

Would it be possible to add chronos support to prologue? I am trying to create a project in prologue that requires a more robust http client system then asynchttpclient + asyncdispatch provides. Correct me if I’m wrong, but chronos also just seems to be more robust in general.

Anyway I would appreciate chronos support.

With some guidance I am willing to make a PR myself.

Edit: I just read some things on another issue that said chronos was slow and inefficient. I would appreciate it if someone told me if I was going in the wrong direction. A custom http 1.1 client might be needed. If I do end up creating something due to time restrictions then I will close this issue.

PhilippMDoerner commented 2 hours ago

I can't say I noticed chronos being slow and inefficient, tbh it likely is receiving more care than std/asyncdispatch is.

As for how you could add chronos support:

It essentially means abstracting away async inside a module which allows you to swap between async implementaions with a when defined(someFlag) switch. Then you just use that async abstraction rather than asyncdispatch directly which is what currently happens. Luckily they should already be decently close in their API, chronos just misses the odd proc here or there from std/asyncdispatch or has them by a different name (in a few rare cases they also refuse to implement them like poll as they lead to bad async designs).

So essentially:

  1. Look at all *.nim files in prologue that import asyncdispatch. Look into which pieces of asyncdispatch they're using to see what needs abstracting away
  2. Make a module to contain the async abstraction, like "customAsync.nim" or whatever decent name strikes you. Within that module you make available all the symbols used from asyncdispatch that you figured out in step 1. Do that via a when statement that by default just exports all the stuff from asyncdispatch, and given a specific flag instead exports chronos. If asyncdispatch provides a symbol that prologue uses and that chronos doesn't have, you'll need to figure out how to implement it. Or if chronos just named it differently, just rename the proc in your async-abstraction-module
  3. Replace the imports of asyncdispatch in all prologue modules with the custom module
  4. Run the test-suite to make sure everything still works, then write some tests to ensure that the chronos part also works in a dedicated folder with its own nim.cfg file that enforces usage of your flag that triggers chronos.

Your endresult for the async module should be looking sth like:

# customAsync.nim
when defined(asyncChronos):
  import chronos
  ... code that makes up for symbols that asyncdispatch has but chronos doesn't ...
  export chronos, allTheOtherSymbols
else:
  import std/asyncdispatch
  export asyncdispatch