vere: implements initial kelvin negotiation with %wyrd/%wend

This commit is contained in:
Joe Bryan 2020-11-04 22:51:49 -08:00
parent 37f26b55e2
commit 8616497c36
5 changed files with 227 additions and 14 deletions

View File

@ -1226,6 +1226,7 @@
# define c3__weak c3_s4('w','e','a','k')
# define c3__web c3_s3('w','e','b')
# define c3__wet c3_s3('w','e','t')
# define c3__wend c3_s4('w','e','n','d')
# define c3__werp c3_s4('w','e','r','p')
# define c3__west c3_s4('w','e','s','t')
# define c3__what c3_s4('w','h','a','t')

View File

@ -542,8 +542,9 @@
u3_psat_init = 0, // initialized
u3_psat_boot = 1, // bootstrap
u3_psat_play = 2, // replaying
u3_psat_work = 3, // working
u3_psat_done = 4 // shutting down
u3_psat_wyrd = 3, // versioning
u3_psat_work = 4, // working
u3_psat_done = 5 // shutting down
} u3_psat;
/* u3_boot: bootstrap event sequence

View File

@ -53,6 +53,14 @@ _hind_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad)
ret_o = c3y;
u3l_log("<<<reset>>>\n");
} break;
// NB: startup explicitly handled in pier.c
//
// XX review arvo upgrade scenaria
//
case c3__wend: {
ret_o = c3y;
} break;
}
}

View File

@ -1090,6 +1090,7 @@ u3_lord_init(c3_c* pax_c, c3_w wag_w, c3_d key_d[4], u3_lord_cb cb_u)
{
u3_lord* god_u = c3_calloc(sizeof *god_u);
god_u->liv_o = c3n;
god_u->pin_o = c3n;
god_u->wag_w = wag_w;
god_u->bin_c = u3_Host.wrk_c; // XX strcopy
god_u->pax_c = pax_c; // XX strcopy

View File

@ -285,7 +285,8 @@ _pier_on_lord_work_spin(void* ptr_v, u3_atom pin, c3_o del_o)
{
u3_pier* pir_u = ptr_v;
c3_assert( (u3_psat_work == pir_u->sat_e)
c3_assert( (u3_psat_wyrd == pir_u->sat_e)
|| (u3_psat_work == pir_u->sat_e)
|| (u3_psat_done == pir_u->sat_e) );
u3_term_start_spinner(pin, del_o);
@ -298,7 +299,8 @@ _pier_on_lord_work_spun(void* ptr_v)
{
u3_pier* pir_u = ptr_v;
c3_assert( (u3_psat_work == pir_u->sat_e)
c3_assert( (u3_psat_wyrd == pir_u->sat_e)
|| (u3_psat_work == pir_u->sat_e)
|| (u3_psat_done == pir_u->sat_e) );
u3_term_stop_spinner();
@ -402,15 +404,16 @@ u3_pier_spin(u3_pier* pir_u)
{
// XX return c3n instead?
//
c3_assert( (u3_psat_work == pir_u->sat_e)
|| (u3_psat_done == pir_u->sat_e) );
if ( u3_psat_work == pir_u->sat_e
|| u3_psat_done == pir_u->sat_e )
{
u3_work* wok_u = pir_u->wok_u;
if ( !uv_is_active((uv_handle_t*)&wok_u->idl_u) ) {
uv_idle_start(&wok_u->idl_u, _pier_work_idle_cb);
}
}
}
/* u3_pier_peek(): read namespace.
*/
@ -488,8 +491,7 @@ _pier_work_init(u3_pier* pir_u)
{
u3_work* wok_u;
c3_assert( (u3_psat_init == pir_u->sat_e)
|| (u3_psat_play == pir_u->sat_e) );
c3_assert( u3_psat_wyrd == pir_u->sat_e );
pir_u->sat_e = u3_psat_work;
pir_u->wok_u = wok_u = c3_calloc(sizeof(*wok_u));
@ -552,6 +554,206 @@ _pier_work_init(u3_pier* pir_u)
_pier_work(wok_u);
}
/* _pier_wyrd_good(): %wyrd version negotation succeeded.
*/
static void
_pier_wyrd_good(u3_pier* pir_u, u3_ovum* egg_u, u3_gift* gif_u)
{
// restore event callbacks
//
{
u3_lord* god_u = pir_u->god_u;
god_u->cb_u.work_done_f = _pier_on_lord_work_done;
god_u->cb_u.work_bail_f = _pier_on_lord_work_bail;
}
// initialize i/o drivers
//
_pier_work_init(pir_u);
// plan %wyrd effects
//
_pier_gift_plan(pir_u->wok_u, gif_u);
// free %wyrd driver and ovum
//
{
u3_auto* car_u = egg_u->car_u;
u3_auto_done(egg_u);
c3_free(car_u);
}
}
/* _pier_wyrd_fail(): %wyrd version negotation failed.
*/
static void
_pier_wyrd_fail(u3_pier* pir_u, u3_ovum* egg_u, u3_noun lud)
{
// XX version negotiation failed, print upgrade message
//
u3l_log("pier: version negotation failed\n\n");
// XX only print trace with -v ?
//
u3_auto_bail_slog(egg_u, lud);
// free %wyrd driver and ovum
//
{
u3_auto* car_u = egg_u->car_u;
u3_auto_done(egg_u);
c3_free(car_u);
}
u3_pier_bail(pir_u);
}
// XX organizing version constants
//
#define VERE_NAME "vere"
#define VERE_MAJOR 0
#define VERE_MINOR 10
#define VERE_PATCH 9
#define VERE_ZUSE 309
/* _pier_wyrd_aver(): check for %wend effect and version downgrade. RETAIN
*/
static c3_o
_pier_wyrd_aver(u3_noun act)
{
u3_noun fec, kel, ver;
// XX review, %wend re: %wyrd optional?
//
while ( u3_nul != act ) {
u3x_cell(act, &fec, &act);
if ( c3__wend == u3h(fec) ) {
kel = u3t(fec);
// traverse $wynn, check for downgrades
//
while ( u3_nul != kel ) {
u3x_cell(kel, &ver, &kel);
// check for %zuse downgrade
//
if ( (c3__zuse == u3h(ver))
&& (VERE_ZUSE != u3t(ver)) )
{
return c3n;
}
// XX in the future, send %wend to serf
// to also negotiate downgrade of nock/hoon/&c?
// (we don't want to have to filter effects)
//
}
}
}
return c3y;
}
/* _pier_on_lord_wyrd_done(): callback for successful %wyrd event.
*/
static void
_pier_on_lord_wyrd_done(void* ptr_v,
u3_ovum* egg_u,
u3_fact* tac_u,
u3_gift* gif_u)
{
u3_pier* pir_u = ptr_v;
c3_assert( u3_psat_wyrd == pir_u->sat_e );
// arvo's side of version negotiation succeeded
// traverse [gif_y] and validate
//
if ( c3n == _pier_wyrd_aver(gif_u->act) ) {
u3_fact_free(tac_u);
u3_gift_free(gif_u);
// XX messageing
//
u3l_log("pier: version negotiation failed; downgrade\n");
_pier_wyrd_fail(pir_u, egg_u, u3_nul);
}
else {
// enqueue %wyrd event-log commit
//
u3_disk_plan(pir_u->log_u, tac_u);
// finalize %wyrd success
//
_pier_wyrd_good(pir_u, egg_u, gif_u);
}
}
/* _pier_on_lord_wyrd_bail(): callback for failed %wyrd event.
*/
static void
_pier_on_lord_wyrd_bail(void* ptr_v, u3_ovum* egg_u, u3_noun lud)
{
u3_pier* pir_u = ptr_v;
c3_assert( u3_psat_wyrd == pir_u->sat_e );
// print %wyrd failure and exit
//
// XX check bail mote, retry on %intr, %meme, &c
//
_pier_wyrd_fail(pir_u, egg_u, lud);
}
/* _pier_wyrd_init(): send %wyrd.
*/
static void
_pier_wyrd_init(u3_pier* pir_u)
{
u3_lord* god_u = pir_u->god_u;
pir_u->sat_e = u3_psat_wyrd;
u3l_log("vere: checking version compatiblity\n");
_pier_work_time(pir_u);
u3v_numb();
{
u3_noun ver = u3nq(u3i_string(VERE_NAME), VERE_MAJOR, VERE_MINOR, VERE_PATCH);
u3_noun kel = u3nl(u3nc(c3__zuse, VERE_ZUSE), // XX god_u->zus_w
// u3nc(c3__lull, PIER_LULL), // XX define
// u3nc(c3__arvo, god_u->arv_y), // XX from both king and serf?
u3nc(c3__hoon, god_u->hon_y),
u3nc(c3__nock, god_u->noc_y),
u3_none);
u3_noun wir = u3nc(c3__arvo, u3_nul);
u3_noun cad = u3nt(c3__wyrd, u3nc(u3k(u3A->sen), ver), kel);
{
u3_auto* car_u = c3_calloc(sizeof(*car_u));
u3_ovum* egg_u = u3_ovum_init(0, u3_blip, wir, cad);
u3_noun ovo;
car_u->pir_u = pir_u;
car_u->nam_m = c3__wyrd;
u3_auto_plan(car_u, egg_u);
// instead of subscribing with u3_auto_peer(),
// we swizzle the [god_u] callbacks for full control
//
god_u->cb_u.work_done_f = _pier_on_lord_wyrd_done;
god_u->cb_u.work_bail_f = _pier_on_lord_wyrd_bail;
c3_assert( u3_auto_next(car_u, &ovo) == egg_u );
u3_lord_work(god_u, egg_u, ovo);
}
}
}
/* _pier_play_plan(): enqueue events for replay.
*/
static void
@ -730,7 +932,7 @@ _pier_play(u3_play* pay_u)
}
else if ( pay_u->eve_d == log_u->dun_d ) {
u3_lord_save(pir_u->god_u);
_pier_work_init(pir_u);
_pier_wyrd_init(pir_u);
}
}
else {
@ -1188,7 +1390,7 @@ _pier_on_lord_live(void* ptr_v)
_pier_play_init(pir_u, eve_d);
}
else {
_pier_work_init(pir_u);
_pier_wyrd_init(pir_u);
}
}
}