vapor / queues

A queue system for Vapor.
MIT License
169 stars 41 forks source link

better type-safety on job dispatch #38

Closed tanner0101 closed 5 years ago

tanner0101 commented 5 years ago

Currently job handlers are looked up by their Data associated type. This could lead to a potential ambiguity. For example, what would happen if two job handlers used [String: String] as their data type?

Maybe we could do something like:

func dispatch<Job>(_ job: Job.Type, _ data: Job.Data) { ... }

That could look like:

req.jobs.dispatch(EmailJob.self, .init(message: "hi"))
jdmcd commented 5 years ago

I'm not sure your suggested solution would actually solve the problem, right? What would it look like if they were using [String: String] as the data type?

req.jobs.dispatch(Dictionary<String, String>.self, ["foo": "bar"])

This goes a little bit deeper into an existential issue that has existed since the beginning of Jobs which is that the way we track configured jobs is not guaranteed to be deterministic for every possible input (not within multiple runs of the same input).

For example, if I have the follow jobs:

struct JobOne: Job {
    struct Data: JobData { }
}

struct JobTwo: Job {
    struct Data: JobData { }
}

Both jobs during registration will try to use the key Data, which isn't good.

tanner0101 commented 5 years ago

In the [String: String] case, I was imagining something like:

struct FooJob: Job { 
    typealias Data = [String: String]
}
struct BarJob: Job {
    typealias Data = [String: String]
}

With dispatching looking like:

req.jobs.dispatch(FooJob.self, ["foo": "bar"])
req.jobs.dispatch(BarJob.self, ["foo": "bar"])

I think we could achieve this internally by using the job handler (Job)'s name as the "job name" instead of the job data. The job handler type is guaranteed to be unique even if it uses the same data type as another job.

jdmcd commented 5 years ago

Ah, I see. That could work!