Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define the concurrency model and libraries to be used #3

Open
hamax97 opened this issue Jun 7, 2023 · 7 comments
Open

Define the concurrency model and libraries to be used #3

hamax97 opened this issue Jun 7, 2023 · 7 comments

Comments

@hamax97
Copy link
Owner

hamax97 commented Jun 7, 2023

@hamax97
Copy link
Owner Author

hamax97 commented Jun 13, 2023

Async and the fiber scheduler introduced in Ruby 3 seem like a great option

@hamax97
Copy link
Owner Author

hamax97 commented Jun 24, 2023

TODOs:

  • Learn how async works.
  • Learn how to use async-rspec.
  • Find (design) the way to wrap the execution part of the application inside Async.
  • Maybe I can learn from the Falcon web server.

@hamax97
Copy link
Owner Author

hamax97 commented Jul 13, 2023

At the moment, using async seems like a great option. See the first acceptance spec created. It can run 100 tps by inserting random sleeps between 0.1 and 0.5 seconds.

@hamax97
Copy link
Owner Author

hamax97 commented Aug 15, 2023

I decided to go with:

  • 1 unit of execution for the executor.
  • 1 unit of execution for the reporter.
  • 1 unit of execution for the counter of tps.

Each unit of execution can be a thread/ractor/process. I found that using Async with Ractors causes many problems and there's no support for solving those issues in Async yet, see this issue 128. It's important to use Async for a more scalable injection of load.

Also, I think using only threads will not make much difference from using only Async, except that I would have to implement synchronization mechanisms for threads, which would be harder.

For now, I'll try using multiple processes, perhaps with async-container, and I'll figure out a mechanisms for communicating between those processes. Processes are better isolated and I would be able to use Async freely inside each process. Some of the drawbacks would be: a higher memory usage, and a slower communication channel between the components (executor, counter, reporter)

@hamax97
Copy link
Owner Author

hamax97 commented Aug 15, 2023

I don't see the poing on using async-container at the moment. Regular fork calls that use Async inside them, with the Queue provided by the multiprocessing gem should be enough for now.

One of the main features of async-container is to provide a mechanism for restarting processes when they fail, but I don't see how that would benefit me. Also, I don't see that it provides a mechanism for custom communication between processes.

@hamax97
Copy link
Owner Author

hamax97 commented Aug 15, 2023

After iterating over different design ideas I'll try to implement the following:

  • An observable object that counts the TPS per second. This observable object will notify listeners twice in a second: (1) once the second starts; (2) once the second finishes. This counter will reset the counter to 0 when each second finishes.
  • An executor that will listen for the beginning_of_second_event. A new execution will be started per each notification. Each execution will try to reach the desired tps that was set when creating the executor.
  • A reporter that will subscribe to the end_of_second_event. It will register (somewhere) the current tps reached during this second together with a timestamp.

Each of these objects will be running in a separate process.
Each process will use Async to avoid blocking on the notifications/executions/reportings.
The mechanism to communicate between these processes will be pipes by using the Queue provided by the multiprocessing gem.

@hamax97
Copy link
Owner Author

hamax97 commented Sep 4, 2023

Look at the design idea I created. You should read this article first, it's nice: https://shopify.engineering/ruby-execution-models

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant