improvement: Add internal queue package and external set package #11
No reviewers
Labels
No labels
🤖 fix nits
🧠 ai fix nits
autorelease
bug
do not merge
documentation
duplicate
enhancement
good first issue
help wanted
invalid
merge when ready
no changelog
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
golibs/go-tasks!11
Loading…
Reference in a new issue
No description provided.
Delete branch "ksimons/addQueue"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Generate changelog in
changelog/@unreleasedType (Select exactly one)
Description Ksimons/add queue
Check the box to generate changelog(s)
✅ Successfully generated changelog entry!
Entry generated via PR title
To modify this entry, edit PR title using proper format.
📋Changelog Preview
💡 Improvements
Thanks -- mostly done with review, but ran out of time. However, wanted to submit what I have so far, especially since the queue comparable type issue is a major one.
@ -0,0 +1,182 @@// Copyright (c) 2025 Palantir Technologies. All rights reserved.Comment is on wrong function (on
GetWithCallbackinstead ofGet).Not sure if you want to duplicate the documentation from interface functions or not.
@ -0,0 +1,114 @@// Copyright (c) 2025 Palantir Technologies. All rights reserved.This doesn't work -- you're basically tricking the compiler, but ultimately
queueItemis the type used forCollapsingQueue, and if the type stored initemis notComparable, then this will panic at runtime.You can observe this by adding the following code to the
TestQueue_AddAndGettest:Results in:
Can reply in more detail later, but here are a few ways I can think of to approach this:
comparable(not great because it's more restrictive)CollapsingQueueso that it basically has aKeytype andValuetype -- if you use amapinstead ofSetfor internal storage, then without too much overhead/change you should be able to do all the enqueue/dequeue logic on keys, but associate with value. However, will make API a bit heavier.CollapsingQueuetakes either acomparableOR an interface that implementsKey()-- if this is done effectively and decomped right, I think it gives the best of both worlds, where you can create queues with comparable types directly, or allow objects to be queued as long as they have aKey()function that returns a comparable to use as the queue keyQueueItem[T comparable]with functionKey() Tand provide a convenience function/constructor that accepts anycomparabletype directly without having to have clients define their own typesI think 4 might be the most straightforward.
For 3, started playing around with the following, but didn't have time to finish locally:
Would recommend adding an
Iteratorfunction (although not firm on naming -- can beAll()orElements()or something like that instead), since that's standard in Go now and will allow for easier usage with packages likeslices.Fine to keep this, but if we add the
Iteratorfunction above, not sure if it's needed -- we can range over elements usingfor elem := range s.Iterator(), and if we actually do want a slice, we can still do it as a one-liner usingslices.Collect(s.Iterator()).Thanks! Mostly looks good -- just a functional question about whether it is intended that callback function is called even when
shutdown=trueand no item is dequeued, and a few suggestions for documentation.@ -0,0 +1,182 @@// Copyright (c) 2025 Palantir Technologies. All rights reserved.As structured,
callback()will be called even if the queue is shutting down and this function returns*new(T), true-- is that intentional/desired?@ -0,0 +1,114 @@// Copyright (c) 2025 Palantir Technologies. All rights reserved.It took me a while to understand the differences between the functions even when looking at implementation, so tried to update documentation to be a bit clearer. However, feel free to modify as needed (or if anything here is incorrect).
@ -0,0 +21,4 @@// by a corresponding Get(). This is suitable for task queues where every submitted// item must be processed exactly once.//// The type parameter T can be any type since no comparison is needed.@ -0,0 +35,4 @@Get() (item T, shutdown bool)// GetWithCallback is like Get but invokes the callback while holding the queue// lock, before returning. This can be used to perform atomic operations when// an item is dequeued.Per other comment, not sure if this behavior is intended, but if it is then I think it should be documented since it's not obvious.
If this is not intended, we can probably update documentation to state that callback will only be invoked if function actually dequeues an element and returns with shutdown=false.
@ -0,0 +1,34 @@// Copyright (c) 2025 Palantir Technologies. All rights reserved.Fixed up comment to reflect type name and clarify (in the context of this package,
Queueis a job queue interface, and this type doesn't implement that)@ -0,0 +47,4 @@got, shutdown = q2.Get()assert.Equal(t, got(), "goodbye, world")assert.False(t, shutdown)}Can we add logic to test the "Get" portion as well per name of test?
@ -0,0 +35,4 @@Get() (item T, shutdown bool)// GetWithCallback is like Get but invokes the callback while holding the queue// lock, before returning. This can be used to perform atomic operations when// an item is dequeued.Changed the comment to reflect that we no-long invoke the callback
@ -0,0 +1,182 @@// Copyright (c) 2025 Palantir Technologies. All rights reserved.Nope, modified to not invoke if its shutting down
Released v0.2.0