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

RFD: Task returns, workers gone awry and handy abstractions #2

Open
KennethWilke opened this issue Jun 16, 2022 · 1 comment
Open
Assignees
Labels
RFD Request For Discussion

Comments

@KennethWilke
Copy link
Owner

KennethWilke commented Jun 16, 2022

Looking to improve a few things and gather wider feedback based on suggestions from @moosingin3space

Task returns

The first idea is around getting a return type or error out of a worker thread. The idea being that if a worker task completes, or bubbles up an error, you can get to that result. My current inclination is to add another generic for the task return type:

diff --git a/src/worker.rs b/src/worker.rs
index 0c45c1c..0931007 100644
--- a/src/worker.rs
+++ b/src/worker.rs
@@ -7,7 +7,7 @@ use crate::request::TenoriteRequest;
 /// This trait specifies the worker end of the service. the `task()` method is
 /// what implements the server side logic.
 #[async_trait]
-pub trait TenoriteWorker<Request, Response, Error, TaskConfig>
+pub trait TenoriteWorker<Request, Response, Error, TaskConfig, TaskResult>
     where Request: Debug,
           Response: Debug,
           Error: Debug,
@@ -16,5 +16,5 @@ pub trait TenoriteWorker<Request, Response, Error, TaskConfig>
     async fn task(
         mut receiver: Receiver<TenoriteRequest<Request, Response, Error>>,
         config: TaskConfig,
-    );
+    ) -> TaskResult;
 }

This feels like a pretty simple and permissive option. Currently returns aren't supported so the JoinHandle wraps the () type. This would instead use the generic JoinHandle<TaskResult>

Another alternative that came up was having an abstracted handler structure returned that has some additional channels for errors or some other kind of control plane specific use

Workers gone awry

Worker panic handling or better reactions if a service's 💩 hits the fan. This would be nice but I don't currently have any good solutions

More concurrent concurrency

There are probably a few other good async message patterns that can be similarly abstracted. The core tokio channel types are simple enough to use but probably other good models or components are waiting to be found. I don't have any concrete ideas but some thoughts are:

  • pipeline pattern
    • instead of returning a result to the caller, return to an additional pipeline block or use an async closure
    • tower or something else may already fit this need pretty well
  • a fan-out/fan-in pattern
    • requests into a single source channel distribute to a parralel task pool and sink into a single output channel
  • pubsub pattern
    • subscribe to channel, listening for an enum variant?
  • router / load balancer / proxy pattern
    • similar to current client/service model but with a dynamic routing element
    • proxies requests based on user-pluggable scheduler or commonly used patterns

Cleaner Implementation

I'm hopeful there's also a way to simplify all the generics clutter when implementing a service. I've been experimenting with macros and maybe there's a good pattern there for simplifying the process of getting all the right types where they need to go without being an eyesore with minimal cognitive load.

Alternatively, maybe another layer can be used, some type of container for a group of related generic types.

Assumptions check

A few trade-offs were made to achieve a nice usage pattern, and some core choices were hastily made to quiet that pesky compiler with all its helpful advice. Sure cargo, it's all 'static and Send or Debug or whatever you want from me! I like this usage pattern so I'll just give you all the trait bounds you want!!

This mostly happened in TenoriteService, but if anyone finds these needlessly restricting or has other assumptions to challenge I'm very open to suggestions on that front

@KennethWilke KennethWilke added the RFD Request For Discussion label Jun 16, 2022
@KennethWilke KennethWilke self-assigned this Jun 16, 2022
@KennethWilke
Copy link
Owner Author

Added the TaskResult change to the development branch: 79a1d4a

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

No branches or pull requests

1 participant