-
Notifications
You must be signed in to change notification settings - Fork 33
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
Implementation of Temporalio.Workflows.Semaphore #287
Conversation
} | ||
completion.Result.Completed.Result = |
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.
Should we add an explicit test to cover this? I guess the semaphore tests cover it as well?
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.
Yes, the semaphore test hit this because it was our first Task
-no-result activity (as opposed to just void
). I can add an explicit test.
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.
Hrmm, so ExecuteActivityAsync_SimpleAsyncVoidMethod_Succeeds
tested this and succeeds in CI but I don't know why, digging...
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.
Ok, there are different routes to creating an activity, and that other test didn't test this route. This semaphore test should be sufficient.
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 all LGTM. Just submitting some minor comments I made while reviewing.
* _Technically_ `SemaphoreSlim` does work if only the async form of `WaitAsync` is used without no timeouts and | ||
`Release` is used. But anything else can deadlock the workflow and its use is cumbersome since it must be disposed. | ||
* Be wary of additional libraries' implicit use of the default scheduler. |
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.
* _Technically_ `SemaphoreSlim` does work if only the async form of `WaitAsync` is used without no timeouts and | |
`Release` is used. But anything else can deadlock the workflow and its use is cumbersome since it must be disposed. | |
* Be wary of additional libraries' implicit use of the default scheduler. | |
* _Technically_ `SemaphoreSlim` does work if only the async form of `WaitAsync` is used without timeouts and | |
`Release` is used. But any other usage pattern can deadlock the workflow and its use is cumbersome since it must be disposed. | |
* Be wary of additional libraries' implicit use of the default scheduler. |
|
||
// Send handle back to check | ||
handleCompletion.SetResult(handle); | ||
// This will never complete |
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.
because the update handlers attempt to execute an activity with a semaphore permit held. Since we are attempting to perform more updates than there are available semaphore permits, this will deadlock.
a comment like that would have saved me time reading the tests.
public async Task ExecuteWorkflowAsync_Semaphore_MultipleWaiters() | ||
{ | ||
// This is a basic test of semaphore usage. We will make a semaphore with 2 allowed and 5 | ||
// provided and confirm as we complete some that others can go. |
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.
Nice comment, would appreciate one of those on the stdlib semaphore tests.
Assert.DoesNotContain(waiting, waiting1.Contains); | ||
return waiting; | ||
}); | ||
Assert.Contains(await handle.QueryAsync(wf => wf.Completed), waiting1.Contains); |
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 assertion seems to be saying
Assert that at least one of the
waiting1
items is now completed.
If so, it seems that we could make it stronger and assert that both of them are completed. Clearer to use set operations?
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.
it seems that we could make it stronger and assert that both of them are completed
Yes, I meant this to be Assert.All
or Assert.True
w/ .All
on the query result (set equality doesn't have as simple of assertion tools in .NET). Will set reminder to change.
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.
Assert.True(completed.Count == 5); | ||
return completed; | ||
}); | ||
Assert.Contains(completed.GetRange(0, 2), waiting1.Contains); |
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.
As above, I think we really want to assert that the set of waiting1
items equals the set of items in GetRange(0, 2)
, but we're asserting something weaker IIUC.
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.
Same deal here, I misunderstood Contains(collection, predicate)
, the intent was to check all
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 was changed
Temporalio.Workflows.Semaphore
deterministic semaphore implementationOpening as draft due to a bug that is occurring when cancelling the workflow while waiting on this semaphore (see TODO in test).
Checklist