Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

dlang timing wheels implementation

NotificationsYou must be signed in to change notification settings

ikod/timingwheels

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Timing Wheels Implementation

Timing wheels is data structure to store and retrieve huge number of timers with O(1) complexity (at the cost of grouping them).

See

http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf

https://www.snellman.net/blog/archive/2016-07-27-ratas-hierarchical-timer-wheel/

https://cwiki.apache.org/confluence/display/KAFKA/Purgatory+Redesign+Proposal

Timing wheels do not operate on real time, but on abstract intervals (ticks). When scheduling a timer, you specify the number of ticks before it runs. The duration of the tick is set "outside" of the library and determines the accuracy with which the timers will be executed. Multiple timers can fall into one tick and will be saved and executed together.

This library require from Timer class to implement methodid() which must return some kind of unique ID. Type of this id can be some integer type or string.

API

Seehttps://ikod.github.io/timingwheels/ for actual docs

Schedule timer

schedule(timer, t); - schedule timer for executiont ticks in the future. t must be > 0.

Cancel timer

cancel(timer) - drop timer from wheels. You can't cancel cancelled timer.

Advance

advance(t) - advance wheels ont ticks. Advance on single tick will return all timers scheduled for the next tick (if any).t must be in interval (0, 256].

timeUntilNextEvent

timeUnitNextEvent(Tick, now) return real time to next timer using provided tick duration.

Here is complete example with comments

import std;    globalLogLevel = LogLevel.info;auto rnd =Random(142);/// track executionint  counter;    SysTime last;/// this is our TimerclassTimer    {staticulong __id;privateulong _id;privatestring _name;this(string name)        {            _id = __id++;            _name = name;        }/// must provide id() methodulongid()        {return _id;        }    }enum IOWakeUpInterval =100;// to simulate random IO wakeups in interval 0 - 100.msecs// each tick span some time interval - this is our link with time in realityauto Tick =5.msecs;    TimingWheels!Timer w;    w.init();autodurationToTicks(Duration d)    {// we have to adjust w.now and realtime 'now' before scheduling timerauto real_now =Clock.currStdTime;auto tw_now = w.currStdTime(Tick);auto delay = (real_now- tw_now).hnsecs;return (d+ delay)/Tick;    }voidprocess_timer(Timer t)    {switch(t._name)        {case"periodic":if ( last.stdTime==0)                {// initialize tracking                    last =Clock.currTime-50.msecs;                }auto delta =Clock.currTime- last;                shouldApproxEqual((1e0*delta.split!"msecs".msecs),50e0,1e-1);                writefln("@ %s - delta: %sms (should be 50ms)", t._name, (Clock.currTime- last).split!"msecs".msecs);                last =Clock.currTime;                counter++;                w.schedule(t,durationToTicks(50.msecs));// rearmbreak;default:                writefln("@ %s", t._name);break;        }    }// emulate some random initial delayauto randomInitialDelay = uniform(0,500, rnd).msecs;Thread.sleep(randomInitialDelay);//// start one arbitrary timer and one periodic timer//auto some_timer =new Timer("some");auto periodic_timer =new Timer("periodic");    w.schedule(some_timer,durationToTicks(32.msecs));    w.schedule(periodic_timer,durationToTicks(50.msecs));while(counter<10)    {auto realNow =Clock.currStdTime;auto randomIoInterval = uniform(0, IOWakeUpInterval, rnd).msecs;auto nextTimerEvent = max(w.timeUntilNextEvent(Tick, realNow),0.msecs);// wait for what should happen earlierauto time_to_sleep = min(randomIoInterval, nextTimerEvent);        writefln("* sleep until timer event or random I/O for %s", time_to_sleep);Thread.sleep(time_to_sleep);// make steps if requiredint ticks = w.ticksToCatchUp(Tick,Clock.currStdTime);if (ticks>0)        {auto wr = w.advance(ticks);foreach(t; wr.timers)            {                process_timer(t);            }        }// emulate some random processing timeThread.sleep(uniform(0,5, rnd).msecs);    }}

[8]ページ先頭

©2009-2025 Movatter.jp