-
Notifications
You must be signed in to change notification settings - Fork 3
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
Remove Sample and reimplement #9
Comments
One problem I ran into with the sample idea is that some processes need ticker := multitick.Ticker{ShortInterval:time.Second,
LongInterval:time.Minute}
secTick := ticker.SubscribeShort()
minTick := ticker.SubscribeLong()
select {
case <- secTick:
//do stuff every second
case <- minTick:
//do important stuff every minute
} I like the way this code looks and for me it's easier to reason about ticker := multitick.Ticker{Interval:time.Second}
secTick := ticker.Subscribe()
for {
tick <- secTick
//do stuff every second
if ticker.RandomlyWithin(time.Minute) == tick {
//do important stuff every minute
}
} But to my surprise, I didn't realize that the time.Ticker would drop ticks. Along a different topic. I like the idea of tickers subscribing to other secTicker := multitick.Ticker{Interval:time.Second}
minTicker := secTicker.OnceEvery(60)
minTickerWithJitter := secTicker.OnceRandomlyWithinEvery(60)
minTickerWithJitterButWait1MinToStart := minTickerWithJitter.Wait(1)
bufferedMinuteTicker := minTicker.Buffered(10) //will start dropping after buffer is full
guaranteedMinuteTicker := minTicker.Guaranteed() //will pause until it can be consumed |
Something like I do like the naming of I don't think we can make the channels buffered without causing bugs. If ticks can pile up and then be delivered late, that makes it really hard to reason about what might happen in every possible case. It also breaks expectations that a multitick behaves like a time.Ticker with broadcasting. That expectation, by the way, is one of the reasons that I think the |
Remove Sample() until after a decision on #9
Conceptually, a multiticker is a ticker and a multiplexor. It would actually be useful to make a multiplexor component and build a multiticker out of that plus a ticker. Two useful things to add into this mix would be a filter that can provide the OnceEvery() functionality, and a smoother that can round the ticks to the desired precision (which will be necessary for OnceEvery() to work right). Then you could build a multiticker, and use it to construct a OnceEvery. The OnceEvery would be implemented as a filter and a multiplexor. I think I'm going to hack on this. It feels like the right decomposition into independent bits of functionality and can be done without any interface changes. |
I lied. It wasn't as clean as I thought. This isn't important so it's on the back burner again. |
I call dibs once it's front burner again. MultiTicker beat me once, but -John On Fri, Mar 7, 2014 at 3:02 PM, Baron Schwartz [email protected]:
|
First a little background. I will share some details of how we use multitick, but guard some of the specifics since not all of that code is open-source.
In many places where we use multitick, especially agents, we want the following functionality:
In our internal codebase we currently accomplish this with something called
RandomlyWithin()
. This is based on a technique I learned from a colleague years ago. This is part of a larger bit of code, but for context, I think it's enough to say that we have an internalts
package that provides time functionality for aTs
type, which is Unix timestamps (integers). In that package, we have code like this:So this is selecting an offset within the selected interval
dur
, based on the start period of the interval, and with some additional offset the caller can pass in.Every time interval will have exactly one timestamp that satisfies the test. For example, if you ask if a timestamp is
RandomlyWithin(ts.Minute)
you will get a result for exactly one timestamp during that minute. This property is important because it does not rely on the application state. That is, if you have a process doing this once a minute and you restart it, there is no possibility that it will take a selected action twice in the minute.Note that the function doesn't return true/false whether the given timestamp is the chosen one. It returns the chosen one. This can be useful because the calling application can then do things like countdowns; even if the selected timestamp isn't the chosen one, it knows which one will be chosen (or if that's already passed).
We use this code in our applications roughly like the following:
We were planning to move this functionality into multitick with the
Sample()
function, and make it appropriate for more general use cases, but after implementing it a little differently and looking at it, it doesn't really do what we want in some ways. So I think we need to reimplement it.Here are two ideas I've had while thinking about this.
ts.RandomlyWithin()
as shown above. The advantages of this are that extra ability to do things like figure out when the tick you're waiting for is coming. The pattern for use would then look pretty similar to the above code.I'm looking for suggestions and feedback.
The text was updated successfully, but these errors were encountered: