Update storage driver store context metadata#1399
Update storage driver store context metadata#1399jmaeagle99 wants to merge 18 commits intotemporalio:mainfrom
Conversation
fcb36db to
5a19712
Compare
drewhoskins-temporal
left a comment
There was a problem hiding this comment.
re: your comments on CaN -- sequence # is an interesting idea.
| """The serialization context active when this store operation was initiated, | ||
| or ``None`` if no context has been set. | ||
| """ | ||
| target: StorageDriverActivityInfo | StorageDriverWorkflowInfo | None = None |
There was a problem hiding this comment.
"target" struck me as odd since it's an info rather than a target. then my second thought was that target would be "where it's stored" rather than "what's being called."
Maybe callee_info or something?
There was a problem hiding this comment.
Like you said, target might not be the best name here. It implies where something should be stored, which is what the information is hinting at. It's trying to say "use this information for storing the payload in a structured manner".
Implementation wise, the target could be the current context or the other size of the serialization boundary. So calling it caller or callee would be wrong in a handful of scenarios. For example, if this was invoke for the result of a completing workflow, it's the "caller" information if it's the top-level workflow but is the "callee" information if the workflow has a parent. Because we want to store it (in terms of S3 terminology) the key prefix for the object that needs it for replay and for lifecycle management. So the API is opinionated as to what information should be used for storing in some kind of hierarchy.
Maybe:
context_info? Feels generic.hierarchy_info? Why is the API telling me about a hierarchy when there isn't an obvious prescription of how to generate the hierarchy? Maybe the API should be offering a visitor for prescriptive ordering and layering of the information.
| For payloads being stored on behalf of an explicit target (e.g. a child | ||
| workflow being started, an activity being scheduled, an external workflow | ||
| being signaled), this is that target's identity. When no explicit target | ||
| exists the current execution context (workflow or activity) is used as the |
There was a problem hiding this comment.
separate caller_info field ? Feels like glossing over this distinction between source and target or caller and callee could result in bugs. Would rather callsites explicitly say what they want to refer to.
There was a problem hiding this comment.
During code review, we talked about the idea of providing both "caller" and "callee" information and felt that it was ambiguous as to how a driver author was supposed to use them, because you don't always store in the callee context.
When talking in terms of the S3 driver, there was an overall pattern of we always want to store the information in a key space that best suits itself for replay and for lifecycle management. That mostly meant the "target workflow" (e.g. child workflow, external signal, CaN, completing workflow that does have a parent) but is sometimes the the current workflow" (e.g. workflow activities, completing workflow that doesn't have a parent); sometimes it is the "current activity" (completing standalone activity) but is sometimes the "target activity" (client starts a standalone activity).
Just providing "caller" and "callee" information isn't enough; you also need to know standalone vs workflow activity. Maybe that's all the extra was needed but the algorithm is not easy to implement.
We felt that this determination would be the same across drivers, if they cared to store payloads in a contextual hierarchy. So it was built into the external storage layer rather than just a concern driver authors had to think about.
What was changed
StorageDriverStoreContext.serialization_contextin favor of a new asymmetric context information system for storage drivers.The S3 driver will now generate all keys (assuming context is provided) such that the key will be in the following formats:
v0/ns/{namespace}/wt/{workflow_type}/wi/{workflow_id}/ri/{run_id}/d/sha256/{hash}for all workflow operations, andv0/ns/{namespace}/at/{activity_type}/ai/{activity_id}/ri/{run_id}/d/sha256/{hash}for standalone activity operations.The
nullsentinel value is used for any token which is not known at during the driver store operation. For example, when starting a workflow from a client, the run ID of the worklfow is not known and will have anullvalue for the{run_id}token.Key Segments by Operation
The overall idea is that payloads are stored into the key space of the target of the operation. The exception is when there is no target (standalone activities results, parentless workflow results), the target is set to the current workflow/activity.
start_workflowwt=type,wi=ID,ri=nullsignal_workflowwt=null,wi=ID,ri=run ID ornullsignal_with_startwt=type,wi=ID,ri=nullexecute_updatewt=null,wi=ID,ri=run ID ornullquery_workflowwt=null,wi=ID,ri=run ID ornullwt=type,wi=ID,ri=nullwt=null,wi=workflow ID,ri=run ID ornullat=null,ai=activity ID,ri=nullwt=type,wi=ID,ri=run IDwt=type,wi=ID,ri=nullwt=null,wi=ID,ri=nullwt=type,wi=ID,ri=run IDwt=type,wi=ID,ri=run IDNo parent workflow: Keyed under current workflow
wt=type,wi=ID,ri=run IDwt=type,wi=ID,ri=run IDStandalone activity: Keyed under current activity
One scenario that needs to be fixed is CaN, but that requires more work in assigning a sequence number an serialization context seems to not support it correctly. Would advocate for fixing separate from this PR.
Why?
SerializationContextChecklist