[Proposal] Package watch and manager/state Watch functions clean up
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 3.7k
- Forks
- 676
- Avg merge
- 4d 9h
- Merged PRs (30d)
- 6
Description
Problem description
When reading the manager/state/store package's code I realized there were different Watch methods and functions in different packages that were tangling the code:
watch.Queuetype has 4 related methods (watch/watch.go):*Queue.Watch() (chan events.Event, func())*Queue.WatchContext(conterxt.Context) (chan events.Event)*Queue.CallbackWatch(events.Matcher) (chan events.Event, func())*Queue.CallbackWatchContext(conterxt.Context, events.Event) (chan events.Event)
statepackage has a function (manager/state/watch.go):Watch(*watch.Queue, ...api.Event) (chan events.Event, func())
store.MemoryStoretype has a related method (manager/state/store/memory.go):*MemoryStore.WatchQueue() *watch.Queue
storepackage also has 2 functions (manager/state/store/memory.go):ViewAndWatch(*MemoryStore, func(ReadTx) error, ...api.Event) (chan events.Event, func(), error)ViewFrom(*MemoryStore, *api.Version, ...api.Event) (chan events.Event, func(), error)
The hetereogenity of functions and methods, using context or cancel functions, etc are tangling the code, which means that the appropiate function is not being used.
watch.Queue
The second and forth methods (the ones using a context.Context instead of giving a cancel function) are not being used except for a single test that can be implemented in a simpler way with the cancel function ones.
The third one (CallbackWatch) is not actually offering a callback as the name suggests. It is actually providing a filter on the events that can be received. FilteredWatch or just Watch (swapping the first to WatchAll`) fit the function better.
state.Watch
This method translates a variadic number of api.Events into an event.Matcher and applies it to the provided *watch.Queue's CallbackWatch method.
Not providing this functionality in the base watch.Queue makes sense as its not something generic, it's specific to the state package, and more specifically to the store.MemoryStore type's queue.
However, providing this functionality as a store.MemoryStore method makes even more sense.
store.MemoryStore
The WatchQueue method name is redundant as it is always followed by one of the watch.Queue watch methods. Furthermore, if the previous change is applied, the access to the queue for the method could be direct. In that case this method will not be needed anymore. This change has a hidden advantage, not returning the Queue would restrict Publishing on it to the MemoryStore which is the only one that should be able to do it.
store.ViewAndWatch
This method uses *MemoryStore.Update just to lock the queue and ensure that the View callback and the Watch channel are in sync, and no event is lost nor sended when it shouldn't. If it is transformed into a MemoryStore method it could access the lock and thus use MemoryStore.View instead.
Additionally it would give this function/method more visibility, as there are several places in the code where it should be used and instead a separate call to Watch and View are being done, thus not completely ensuring the previous conditions.
The View callback also differs in signature, as this method returns an error, making it equal to the Update callback but with different privileges.
store.WatchFrom
Similar to the previous, this method also lacks visibility and uses MemoryStore.Update when it shouldn't.
Proposal
- Delete
watch.Queue's context related methods, simplifying the only remaining use in a test case. - Rename
watch.Queue's remaining methods to improve redability. - Transform
state.Watch,store.ViewAndWatchandstore.WatchFromintostore.MemoryStore's methods. - Make
ViewAndWatchcallback the same thanMemoryStore.View. - Update the cases where two different calls are being made instead of using
ViewAndWatch.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading watch/watch.go, manager/state/watch.go, and manager/state/store/memory.go, then search for all listed Watch, ViewAndWatch, WatchFrom, and WatchQueue call sites. Done means the proposed methods are consolidated or renamed, callers use the updated store methods, and the existing test suite passes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- distributed-systems
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100