vapor/queues

better type-safety on job dispatch

tanner0101 opened this issue · 3 comments

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

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.

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

Ah, I see. That could work!