events: Safer restarting in listenHeadChanges
This commit is contained in:
parent
cc82cc9675
commit
689b1e5b3c
@ -47,7 +47,7 @@ type Events struct {
|
|||||||
calledEvents
|
calledEvents
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEvents(api eventApi) *Events {
|
func NewEvents(ctx context.Context, api eventApi) *Events {
|
||||||
gcConfidence := 2 * build.ForkLengthThreshold
|
gcConfidence := 2 * build.ForkLengthThreshold
|
||||||
|
|
||||||
tsc := newTSCache(gcConfidence, api.ChainGetTipSetByHeight)
|
tsc := newTSCache(gcConfidence, api.ChainGetTipSetByHeight)
|
||||||
@ -81,7 +81,7 @@ func NewEvents(api eventApi) *Events {
|
|||||||
|
|
||||||
e.ready.Add(1)
|
e.ready.Add(1)
|
||||||
|
|
||||||
go e.listenHeadChanges(context.TODO())
|
go e.listenHeadChanges(ctx)
|
||||||
|
|
||||||
e.ready.Wait()
|
e.ready.Wait()
|
||||||
|
|
||||||
@ -90,48 +90,44 @@ func NewEvents(api eventApi) *Events {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Events) restartHeadChanges(ctx context.Context) {
|
func (e *Events) listenHeadChanges(ctx context.Context) {
|
||||||
go func() {
|
for {
|
||||||
|
if err := e.listenHeadChangesOnce(ctx); err != nil {
|
||||||
|
log.Errorf("listen head changes errored: %s", err)
|
||||||
|
} else {
|
||||||
|
log.Warn("listenHeadChanges quit")
|
||||||
|
}
|
||||||
if ctx.Err() != nil {
|
if ctx.Err() != nil {
|
||||||
log.Warnf("not restarting listenHeadChanges: context error: %s", ctx.Err())
|
log.Warnf("not restarting listenHeadChanges: context error: %s", ctx.Err())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
log.Info("restarting listenHeadChanges")
|
log.Info("restarting listenHeadChanges")
|
||||||
e.listenHeadChanges(ctx)
|
}
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Events) listenHeadChanges(ctx context.Context) {
|
func (e *Events) listenHeadChangesOnce(ctx context.Context) error {
|
||||||
notifs, err := e.api.ChainNotify(ctx)
|
notifs, err := e.api.ChainNotify(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: retry
|
// TODO: retry
|
||||||
log.Errorf("listenHeadChanges ChainNotify call failed: %s", err)
|
return xerrors.Errorf("listenHeadChanges ChainNotify call failed: %w", err)
|
||||||
e.restartHeadChanges(ctx)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cur, ok := <-notifs // TODO: timeout?
|
cur, ok := <-notifs // TODO: timeout?
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Error("notification channel closed")
|
return xerrors.Errorf("notification channel closed")
|
||||||
e.restartHeadChanges(ctx)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cur) != 1 {
|
if len(cur) != 1 {
|
||||||
log.Errorf("unexpected initial head notification length: %d", len(cur))
|
return xerrors.Errorf("unexpected initial head notification length: %d", len(cur))
|
||||||
e.restartHeadChanges(ctx)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if cur[0].Type != store.HCCurrent {
|
if cur[0].Type != store.HCCurrent {
|
||||||
log.Errorf("expected first head notification type to be 'current', was '%s'", cur[0].Type)
|
return xerrors.Errorf("expected first head notification type to be 'current', was '%s'", cur[0].Type)
|
||||||
e.restartHeadChanges(ctx)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := e.tsc.add(cur[0].Val); err != nil {
|
if err := e.tsc.add(cur[0].Val); err != nil {
|
||||||
log.Warn("tsc.add: adding current tipset failed: %s", err)
|
log.Warn("tsc.add: adding current tipset failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.readyOnce.Do(func() {
|
e.readyOnce.Do(func() {
|
||||||
@ -156,8 +152,7 @@ func (e *Events) listenHeadChanges(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Warn("listenHeadChanges loop quit")
|
return nil
|
||||||
e.restartHeadChanges(ctx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Events) headChange(rev, app []*types.TipSet) error {
|
func (e *Events) headChange(rev, app []*types.TipSet) error {
|
||||||
|
@ -160,7 +160,7 @@ func TestAt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
||||||
|
|
||||||
events := NewEvents(fcs)
|
events := NewEvents(context.Background(), fcs)
|
||||||
|
|
||||||
var applied bool
|
var applied bool
|
||||||
var reverted bool
|
var reverted bool
|
||||||
@ -219,7 +219,7 @@ func TestAtStart(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
||||||
|
|
||||||
events := NewEvents(fcs)
|
events := NewEvents(context.Background(), fcs)
|
||||||
|
|
||||||
fcs.advance(0, 5, nil) // 6
|
fcs.advance(0, 5, nil) // 6
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ func TestAtStartConfidence(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
||||||
|
|
||||||
events := NewEvents(fcs)
|
events := NewEvents(context.Background(), fcs)
|
||||||
|
|
||||||
fcs.advance(0, 10, nil) // 11
|
fcs.advance(0, 10, nil) // 11
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ func TestCalled(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
||||||
|
|
||||||
events := NewEvents(fcs)
|
events := NewEvents(context.Background(), fcs)
|
||||||
|
|
||||||
t0123, err := address.NewFromString("t0123")
|
t0123, err := address.NewFromString("t0123")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -484,7 +484,7 @@ func TestCalledTimeout(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
||||||
|
|
||||||
events := NewEvents(fcs)
|
events := NewEvents(context.Background(), fcs)
|
||||||
|
|
||||||
t0123, err := address.NewFromString("t0123")
|
t0123, err := address.NewFromString("t0123")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -524,7 +524,7 @@ func TestCalledTimeout(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
||||||
|
|
||||||
events = NewEvents(fcs)
|
events = NewEvents(context.Background(), fcs)
|
||||||
|
|
||||||
err = events.Called(func(ts *types.TipSet) (d bool, m bool, e error) {
|
err = events.Called(func(ts *types.TipSet) (d bool, m bool, e error) {
|
||||||
return true, true, nil
|
return true, true, nil
|
||||||
@ -558,7 +558,7 @@ func TestCalledOrder(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
||||||
|
|
||||||
events := NewEvents(fcs)
|
events := NewEvents(context.Background(), fcs)
|
||||||
|
|
||||||
t0123, err := address.NewFromString("t0123")
|
t0123, err := address.NewFromString("t0123")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -68,8 +68,7 @@ type storageMinerApi interface {
|
|||||||
|
|
||||||
func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, secst *sector.Store, commt *commitment.Tracker) (*Miner, error) {
|
func NewMiner(api storageMinerApi, addr address.Address, h host.Host, ds datastore.Batching, secst *sector.Store, commt *commitment.Tracker) (*Miner, error) {
|
||||||
return &Miner{
|
return &Miner{
|
||||||
api: api,
|
api: api,
|
||||||
events: events.NewEvents(api),
|
|
||||||
|
|
||||||
maddr: addr,
|
maddr: addr,
|
||||||
h: h,
|
h: h,
|
||||||
@ -84,6 +83,8 @@ func (m *Miner) Run(ctx context.Context) error {
|
|||||||
return errors.Wrap(err, "miner preflight checks failed")
|
return errors.Wrap(err, "miner preflight checks failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.events = events.NewEvents(ctx, m.api)
|
||||||
|
|
||||||
ts, err := m.api.ChainHead(ctx)
|
ts, err := m.api.ChainHead(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user