-
-
Notifications
You must be signed in to change notification settings - Fork 0
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
feat(taskbroker): Enable querying for namespace specific tasks #74
Conversation
src/grpc_server.rs
Outdated
if let Some(fetch_next) = request.get_ref().fetch_next { | ||
if fetch_next { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having to provide both fetch_next
and fetch_next_namespace
creates a trap where providing fetch_next_namespace
in isolation will be silently ignored. Perhaps we need two cases, one for fetch_next and one for fetch_next_namespace
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, would it make more sense to redefine fetch_next
using a richer type?
Like
fetch_next: Option<Fetch>
Enum Fetch {
Arbitrary,
ByNamespace(String)
}
I'm not sure how to express this in protobuf and how it will translate via prost, maybe something like
message GetTaskResponse {
...
optional fetchNext fetchNext = 1;
}
message fetchNext {
oneof fetchBy {
string namespace = 1;
google.protobuf.NullValue arbitrary = 2;
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A oneof
could work, I don't think we would need the nested message either.
message SetTaskStatusRequest {
oneof fetch_next_by {
string fetch_namespace = 6;
bool fetch_any = 7;
}
}
We might also be able to adapt the existing fields into a oneof
as oneof
doesn't use up slots in the proto.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, so with
message SetTaskStatusRequest {
oneof fetch_next_by {
string fetch_namespace = 6;
bool fetch_any = 7;
}
}
If use caller does not want to fetch another message, they would set the fetch_any variant to false
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If use caller does not want to fetch another message, they would set the fetch_any variant to false?
Yeah, it can also be left empty (at least in the python bindings).
message SetTaskStatusRequest {
string id = 1;
TaskActivationStatus status = 3;
// Set to true to have receive a new task in the response
optional bool fetch_next = 4;
optional string fetch_next_namespace = 5;
oneof fetch_next_by {
string fetch_namespace = 6;
bool fetch_any = 7;
}
}
And usage of the generated python code
from sentry_protos.sentry.v1.taskworker_pb2 import SetTaskStatusRequest
from sentry_protos.sentry.v1.taskworker_pb2 import TASK_ACTIVATION_STATUS_COMPLETE
>>> req = SetTaskStatusRequest(id="abc", status=TASK_ACTIVATION_STATUS_COMPLETE)
>>> req.fetch_any
False
>>> req.fetch_namespace
''
>>> req = SetTaskStatusRequest(id="abc", status=TASK_ACTIVATION_STATUS_COMPLETE, fetch_any=True)
>>> req.fetch_any
True
>>> req = SetTaskStatusRequest(id="abc", status=TASK_ACTIVATION_STATUS_COMPLETE, fetch_any=True, fetch_namespace="derp")
>>> req
id: "abc"
status: TASK_ACTIVATION_STATUS_COMPLETE
fetch_namespace: "derp"
>>> req.fetch_any
False
It doesn't seem like the generated code will raise an error if both are provided, but only one value is set into the object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah okay, personally a oneof
with a string
/bool
variant is a little less intuitive than an optional
oneof
with a string
/unit
variant for some reason. But I think either is serviceable and it seems like the former is more easily expressed in protobuf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we just use made the fetch_next message itself optional, and use that to replace fetch_any
. It feel like it could be a bit more intuitive than using oneof at all?
For example:
message FetchNext {
optional string namespace = 1;
}
message SetTaskStatusRequest {
string id = 1;
TaskActivationStatus status = 2;
// If fetch_next is provided, receive a new task in the response
optional FetchNext fetch_next = 3;
}
as defined in getsentry/sentry-protos#69
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That works too!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also update the worker in sentry to use the undeprecated parameters.
src/inflight_activation_store.rs
Outdated
"UPDATE inflight_taskactivations | ||
SET | ||
processing_deadline = datetime('now', '+' || processing_deadline_duration || ' seconds'), | ||
status = $1 | ||
WHERE id = ( | ||
SELECT id | ||
FROM inflight_taskactivations | ||
WHERE status = $2 | ||
AND (deadletter_at IS NULL OR deadletter_at > $3) | ||
AND namespace = $4 | ||
ORDER BY added_at | ||
LIMIT 1 | ||
) | ||
RETURNING *", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might be able to use QueryBuilder
to reduce the duplication in these queries. You could initialize the query with the query up to the namespace condition, and then use .push()
and .push_bind()
to add the namespace condition and limit/returning clauses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, using query builder 👍 Though, I find it a bit less legible because query builder requires use to build it piecewise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I miss having an ORM style builder. But I also don't think we have enough complex queries to justify a larger library yet.
1880d83
to
576a656
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good.
src/inflight_activation_store.rs
Outdated
query_builder.push(" ORDER BY added_at LIMIT 1) RETURNING *"); | ||
query_builder | ||
.build_query_as::<TableRow>() | ||
.fetch_optional(&self.sqlite_pool) | ||
.await? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This passage looks the same on both sides of the match arms, could it be moved down? You'd have to move the result
assignment down as well though.
576a656
to
6219a7a
Compare
Now that taskbroker gRPC supports getting tasks by namespace, this PR enables the taskworker to use that parameter if provided. Depends on: getsentry/taskbroker#74
Now that taskbroker gRPC supports getting tasks by namespace, this PR enables the taskworker to use that parameter if provided. Depends on: getsentry/taskbroker#74
Now that taskbroker gRPC supports getting tasks by namespace, this PR enables the taskworker to use that parameter if provided. Depends on: getsentry/taskbroker#74
Overview:
This PR is responsible enabling taskbroker to receive a namespace parameter for the worker client and return pending activations specific for that namespace.
Dependencies:
Refs:
Testing: