Merge pull request #3050 from urbit/m/behn-improvements

behn, vere: some improvements
This commit is contained in:
Fang 2020-06-25 22:38:02 +02:00 committed by GitHub
commit ed808614aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 94 additions and 22 deletions

View File

@ -767,7 +767,7 @@
++ v-behn
|%
++ timers
(scry ,(list [date=@da =duct]) %b %timers ~)
(scry ,(list [date=@da =duct]) %bx %$ /debug/timers)
--
::
:: clay

View File

@ -1,5 +1,5 @@
:: Find list of currently running Behn timers
:- %say
|= *
|= [[now=@da *] *]
:- %tang
[>.^((list [date=@da =duct]) %b /=timers=)< ~]
[>.^((list [date=@da =duct]) %bx /=//(scot %da now)/debug/timers)< ~]

View File

@ -191,7 +191,7 @@
?. ?=({@ @ @ @ *} u.pux) ~
=+ :* hyr=(slaw %tas i.u.pux)
fal=(slaw %p i.t.u.pux)
dyc=(slaw %tas i.t.t.u.pux)
dyc=?~(i.t.t.u.pux (some %$) (slaw %tas i.t.t.u.pux))
ved=(slay i.t.t.t.u.pux)
tyl=t.t.t.t.u.pux
==

View File

@ -389,18 +389,56 @@
++ scry
|= [fur=(unit (set monk)) ren=@tas why=shop syd=desk lot=coin tyl=path]
^- (unit (unit cage))
:: only respond for the local identity, %$ desk, current timestamp
::
?. ?=(%& -.why)
?. ?& =(&+our why)
=([%$ %da now] lot)
=(%$ syd)
==
~
?. ?=(%timers syd)
[~ ~]
=/ tiz=(list [@da duct])
:: /bx/debug/timers (list [@da duct]) all timers and their ducts
:: /bx/timers (list @da) all timer timestamps
:: /bx/timers/next (unit @da) the very next timer to fire
:: /bx/timers/[da] (list @da) all timers up to and including da
::
?. ?=(%x ren) ~
?+ tyl [~ ~]
[%debug %timers ~]
:^ ~ ~ %noun
!> ^- (list [@da duct])
%- zing
%+ turn (tap:timer-map timers)
|= [date=@da q=(qeu duct)]
%+ turn ~(tap to q)
|=(d=duct [date d])
[~ ~ %noun !>(tiz)]
::
[%timers ~]
:^ ~ ~ %noun
!> ^- (list @da)
%- zing
%+ turn (tap:timer-map timers)
|= [date=@da q=(qeu duct)]
(reap ~(wyt in q) date)
::
[%timers %next ~]
:^ ~ ~ %noun
!> ^- (unit @da)
(bind (peek:timer-map timers) head)
::
[%timers @ ~]
?~ til=(slaw %da i.t.tyl)
[~ ~]
:^ ~ ~ %noun
!> ^- (list @da)
=/ tiz=(list [date=@da q=(qeu duct)])
(tap:timer-map timers)
|- ^- (list @da)
?~ tiz ~
?: (gth date.i.tiz u.til) ~
%+ weld
(reap ~(wyt in q.i.tiz) date.i.tiz)
$(tiz t.tiz)
==
::
++ stay state
++ take

View File

@ -16,28 +16,36 @@
typedef struct _u3_behn {
u3_auto car_u; // driver
uv_timer_t tim_u; // behn timer
c3_o alm; // alarm
c3_o alm_o; // alarm
c3_o see_o; // can scry
} u3_behn;
static void _behn_scry_cb(void* vod_p, u3_noun nun);
/* _behn_time_cb(): timer callback.
*/
static void
_behn_time_cb(uv_timer_t* tim_u)
{
u3_behn* teh_u = tim_u->data;
teh_u->alm = c3n;
teh_u->alm_o = c3n;
// start another timer for 10 minutes
// take initiative to start the next timer, just in case
//
// This is a backstop to deal with the case where a %doze is not
// properly sent, for example after a crash. If the timer continues
// to fail, we can't proceed with the timers, but if it was a
// transient error, this will get us past it.
//
{
c3_d gap_d = 10 * 60 * 1000;
teh_u->alm = c3y;
uv_timer_start(&teh_u->tim_u, _behn_time_cb, gap_d, 0);
if (c3y == teh_u->see_o) {
u3_noun pax = u3i_trel(u3i_string("timers"), u3i_string("next"), u3_nul);
u3_lord_peek_last(teh_u->car_u.pir_u->god_u, u3_nul,
c3_s2('b', 'x'), u3_nul, pax,
teh_u, _behn_scry_cb);
}
else {
// if scry is known to not work, short-circuit
_behn_scry_cb(teh_u, u3_nul);
}
// send timer event
@ -59,13 +67,12 @@ _behn_ef_doze(u3_behn* teh_u, u3_noun wen)
teh_u->car_u.liv_o = c3y;
}
if ( c3y == teh_u->alm ) {
if ( c3y == teh_u->alm_o ) {
uv_timer_stop(&teh_u->tim_u);
teh_u->alm = c3n;
teh_u->alm_o = c3n;
}
if ( (u3_nul != wen) &&
(c3y == u3du(wen)) &&
if ( (c3y == u3du(wen)) &&
(c3y == u3ud(u3t(wen))) )
{
struct timeval tim_tv;
@ -74,13 +81,39 @@ _behn_ef_doze(u3_behn* teh_u, u3_noun wen)
u3_noun now = u3_time_in_tv(&tim_tv);
c3_d gap_d = u3_time_gap_ms(now, u3k(u3t(wen)));
teh_u->alm = c3y;
teh_u->alm_o = c3y;
uv_timer_start(&teh_u->tim_u, _behn_time_cb, gap_d, 0);
} else if (u3_nul != wen) {
u3m_p("behn: invalid doze", wen);
}
u3z(wen);
}
/* _behn_scry_cb(): next timer scry result callback.
*/
static void
_behn_scry_cb(void* vod_p, u3_noun nun)
{
u3_behn* teh_u = vod_p;
u3_weak tim = u3r_at(7, nun);
if (c3y == teh_u->alm_o) {
// timer already set while we were scrying, no-op
}
else if (u3_none == tim) {
// remember scry doesn't work, fall back to a timer for 10 minutes
//
teh_u->see_o = c3n;
c3_d gap_d = 10 * 60 * 1000;
teh_u->alm_o = c3y;
uv_timer_start(&teh_u->tim_u, _behn_time_cb, gap_d, 0);
} else {
_behn_ef_doze(teh_u, u3k(tim));
}
u3z(nun);
}
/* _behn_io_talk(): notify %behn that we're live
*/
static void
@ -143,7 +176,8 @@ u3_auto*
u3_behn_io_init(u3_pier* pir_u)
{
u3_behn* teh_u = c3_calloc(sizeof(*teh_u));
teh_u->alm = c3n;
teh_u->alm_o = c3n;
teh_u->see_o = c3y;
uv_timer_init(u3L, &teh_u->tim_u);
teh_u->tim_u.data = teh_u;