44
55from temporalio import workflow
66
7- from resource_locking .shared import (
8- AcquireRequest ,
9- AcquireResponse ,
10- )
7+ from resource_locking .shared import AcquireRequest , AcquireResponse
8+
119
1210# Internal to this workflow, we'll associate randomly generated release signal names with each acquire request.
1311@dataclass
1412class InternalAcquireRequest (AcquireRequest ):
1513 release_signal : Optional [str ]
1614
15+
1716@dataclass
1817class LockManagerWorkflowInput :
1918 # Key is resource, value is current lock holder for the resource (None if not locked)
2019 resources : dict [str , Optional [InternalAcquireRequest ]]
2120 waiters : list [InternalAcquireRequest ]
2221
22+
2323@workflow .defn
2424class LockManagerWorkflow :
2525 @workflow .init
@@ -28,7 +28,7 @@ def __init__(self, input: LockManagerWorkflowInput):
2828 self .waiters = input .waiters
2929 self .release_signal_to_resource : dict [str , str ] = {}
3030 for resource , holder in self .resources .items ():
31- if holder is not None :
31+ if holder is not None and holder . release_signal is not None :
3232 self .release_signal_to_resource [holder .release_signal ] = resource
3333
3434 @workflow .signal
@@ -47,7 +47,9 @@ async def add_resources(self, resources: list[str]):
4747
4848 @workflow .signal
4949 async def acquire_resource (self , request : AcquireRequest ):
50- internal_request = InternalAcquireRequest (workflow_id = request .workflow_id , release_signal = None )
50+ internal_request = InternalAcquireRequest (
51+ workflow_id = request .workflow_id , release_signal = None
52+ )
5153
5254 for resource , holder in self .resources .items ():
5355 # Naively give out the first free resource, if we have one
@@ -61,7 +63,9 @@ async def acquire_resource(self, request: AcquireRequest):
6163 f"workflow_id={ request .workflow_id } is waiting for a resource"
6264 )
6365
64- async def allocate_resource (self , resource : str , internal_request : InternalAcquireRequest ):
66+ async def allocate_resource (
67+ self , resource : str , internal_request : InternalAcquireRequest
68+ ):
6569 self .resources [resource ] = internal_request
6670 workflow .logger .info (
6771 f"workflow_id={ internal_request .workflow_id } acquired resource { resource } "
@@ -70,12 +74,19 @@ async def allocate_resource(self, resource: str, internal_request: InternalAcqui
7074 self .release_signal_to_resource [internal_request .release_signal ] = resource
7175
7276 requester = workflow .get_external_workflow_handle (internal_request .workflow_id )
73- await requester .signal ("assign_resource" , AcquireResponse (release_signal_name = internal_request .release_signal , resource = resource ))
77+ await requester .signal (
78+ "assign_resource" ,
79+ AcquireResponse (
80+ release_signal_name = internal_request .release_signal , resource = resource
81+ ),
82+ )
7483
7584 @workflow .signal (dynamic = True )
7685 async def release_resource (self , signal_name , * args ):
7786 if not signal_name in self .release_signal_to_resource :
78- workflow .logger .warning (f"Ignoring unknown signal: { signal_name } was not a valid release signal." )
87+ workflow .logger .warning (
88+ f"Ignoring unknown signal: { signal_name } was not a valid release signal."
89+ )
7990 return
8091
8192 resource = self .release_signal_to_resource [signal_name ]
@@ -85,6 +96,7 @@ async def release_resource(self, signal_name, *args):
8596 workflow .logger .warning (
8697 f"Ignoring request to release resource that is not locked: { resource } "
8798 )
99+ return
88100
89101 # Remove the current holder
90102 workflow .logger .info (
@@ -110,7 +122,9 @@ async def run(self, _: LockManagerWorkflowInput) -> None:
110122 timeout = timedelta (hours = 12 ),
111123 )
112124
113- workflow .continue_as_new (LockManagerWorkflowInput (
114- resources = self .resources ,
115- waiters = self .waiters ,
116- ))
125+ workflow .continue_as_new (
126+ LockManagerWorkflowInput (
127+ resources = self .resources ,
128+ waiters = self .waiters ,
129+ )
130+ )
0 commit comments