feat: storage: Force exit GenerateSingleVanillaProof on cancelled context

This commit is contained in:
Łukasz Magiera 2022-11-09 12:27:45 +01:00
parent 7a99325528
commit 42d02dd448
3 changed files with 57 additions and 1 deletions

35
lib/result/result.go Normal file
View File

@ -0,0 +1,35 @@
package result
// Result is a small wrapper type encapsulating Value/Error tuples, mostly for
// use when sending values across channels
// NOTE: Avoid adding any functionality to this, any "nice" things added here will
// make it more difficult to switch to a more standardised Result-like type when
// one gets into the stdlib, or when we will want to switch to a library providing
// those types.
type Result[T any] struct {
Value T
Error error
}
func Ok[T any](value T) Result[T] {
return Result[T]{
Value: value,
}
}
func Err[T any](err error) Result[T] {
return Result[T]{
Error: err,
}
}
func Wrap[T any](value T, err error) Result[T] {
return Result[T]{
Value: value,
Error: err,
}
}
func (r *Result[T]) Unwrap() (T, error) {
return r.Value, r.Error
}

View File

@ -17,6 +17,7 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/proof"
"github.com/filecoin-project/lotus/lib/result"
"github.com/filecoin-project/lotus/storage/sealer/fsutil"
"github.com/filecoin-project/lotus/storage/sealer/storiface"
)
@ -789,7 +790,18 @@ func (st *Local) GenerateSingleVanillaProof(ctx context.Context, minerID abi.Act
SealedSectorPath: sealed,
}
return ffi.GenerateSingleVanillaProof(psi, si.Challenge)
resCh := make(chan result.Result[[]byte], 1)
go func() {
resCh <- result.Wrap(ffi.GenerateSingleVanillaProof(psi, si.Challenge))
}()
select {
case r := <-resCh:
return r.Unwrap()
case <-ctx.Done():
// this will leave the GenerateSingleVanillaProof goroutine hanging, but that's still less bad than failing PoSt
return nil, xerrors.Errorf("failed to generate valilla proof before context cancellation: %w", ctx.Err())
}
}
var _ Store = &Local{}

View File

@ -7,6 +7,7 @@ import (
"github.com/ipfs/go-cid"
"go.opencensus.io/trace"
"go.uber.org/zap"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
@ -253,6 +254,14 @@ func (s *WindowPoStScheduler) runPoStCycle(ctx context.Context, manual bool, di
ctx, span := trace.StartSpan(ctx, "storage.runPoStCycle")
defer span.End()
start := time.Now()
log := log.WithOptions(zap.Fields(zap.Time("cycle", start)))
log.Infow("starting PoSt cycle", "manual", manual, "ts", ts, "deadline", di.Index)
defer func() {
log.Infow("post cycle done", "took", time.Now().Sub(start))
}()
if !manual {
// TODO: extract from runPoStCycle, run on fault cutoff boundaries
s.asyncFaultRecover(di, ts)