diff --git a/impl/pkg/dht/dht.go b/impl/pkg/dht/dht.go index 90a41bab..9da395d6 100644 --- a/impl/pkg/dht/dht.go +++ b/impl/pkg/dht/dht.go @@ -11,6 +11,7 @@ import ( "github.com/anacrolix/dht/v2" "github.com/anacrolix/dht/v2/bep44" "github.com/anacrolix/dht/v2/exts/getput" + "github.com/anacrolix/dht/v2/traversal" "github.com/anacrolix/log" "github.com/anacrolix/torrent/types/infohash" "github.com/pkg/errors" @@ -95,17 +96,29 @@ func (d *DHT) Put(ctx context.Context, request bep44.Put) (string, error) { t, err := getput.Put(ctx, request.Target(), d.Server, nil, func(int64) bep44.Put { return request }) - if err != nil { - if t == nil { - return "", fmt.Errorf("failed to put key[%s] into dht: %v", key, err) - } - return "", fmt.Errorf("failed to put key[%s] into dht, tried %d nodes, got %d responses", key, t.NumAddrsTried, t.NumResponses) - } else { - logrus.WithContext(ctx).WithField("key", key).Debug("successfully put key into dht") + if err = isPutSuccessful(key, t, err); err != nil { + logrus.WithContext(ctx).WithField("key", key).Error("error putting key into dht") + return "", err } + logrus.WithContext(ctx).WithField("key", key).Debug("successfully put key into dht") return util.Z32Encode(request.K[:]), nil } +const successThreshold = 0.33 + +func isPutSuccessful(key string, t *traversal.Stats, err error) error { + if err != nil { + return nil + } + if t == nil { + return fmt.Errorf("failed to put key[%s] into dht: %v", key, err) + } + if float64(t.NumResponses)/float64(t.NumAddrsTried) < successThreshold { + return fmt.Errorf("failed to put key[%s] into dht, tried %d nodes, got %d responses", key, t.NumAddrsTried, t.NumResponses) + } + return nil +} + // GetFull returns the full BEP-44 result for the given key from the DHT, using our modified // implementation of getput.Get. It should ONLY be used when it's needed to get the signature // data for a record. diff --git a/impl/pkg/service/dht.go b/impl/pkg/service/dht.go index 49a500ae..67d405e2 100644 --- a/impl/pkg/service/dht.go +++ b/impl/pkg/service/dht.go @@ -145,7 +145,7 @@ func (s *DHTService) GetDHT(ctx context.Context, id string) (*dht.BEP44Response, if got, err := s.cache.Get(id); err == nil { var resp dht.BEP44Response if err = json.Unmarshal(got, &resp); err == nil { - logrus.WithContext(ctx).WithField("record_id", id).Info("resolved record from cache") + logrus.WithContext(ctx).WithField("record_id", id).Debug("resolved record from cache") return &resp, nil } logrus.WithContext(ctx).WithError(err).WithField("record_id", id).Warn("failed to get record from cache, falling back to dht") @@ -175,7 +175,7 @@ func (s *DHTService) GetDHT(ctx context.Context, id string) (*dht.BEP44Response, return nil, err } - logrus.WithContext(ctx).WithField("record_id", id).Info("resolved record from storage") + logrus.WithContext(ctx).WithField("record_id", id).Debug("resolved record from storage") resp := record.Response() // add the record back to the cache for future lookups if err = s.addRecordToCache(id, record.Response()); err != nil { @@ -204,7 +204,7 @@ func (s *DHTService) GetDHT(ctx context.Context, id string) (*dht.BEP44Response, if err = s.addRecordToCache(id, resp); err != nil { logrus.WithContext(ctx).WithField("record_id", id).WithError(err).Error("failed to set record in cache") } else { - logrus.WithContext(ctx).WithField("record_id", id).Info("added record back to cache") + logrus.WithContext(ctx).WithField("record_id", id).Debug("added record back to cache") } return &resp, nil @@ -294,7 +294,7 @@ func (s *DHTService) republishRecords(ctx context.Context) []failedRecord { "success": seenRecords - int32(len(failedRecords)), "errors": len(failedRecords), "total": seenRecords, - }).Infof("republishing complete with [%d] batches of [%d] total records with a [%.2f] percent success rate", batchCnt, seenRecords, successRate) + }).Debugf("republishing complete with [%d] batches of [%d] total records with a [%.2f] percent success rate", batchCnt, seenRecords, successRate) return failedRecords }