2016-01-25 06:41:39 +01:00
|
|
|
// Copyright 2016 The Chihaya Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by the BSD 2-Clause license,
|
|
|
|
// which can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package store
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/chihaya/chihaya"
|
2016-06-19 18:49:43 +02:00
|
|
|
"github.com/chihaya/chihaya/pkg/stopper"
|
2016-01-25 06:41:39 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
var peerStoreDrivers = make(map[string]PeerStoreDriver)
|
|
|
|
|
|
|
|
// PeerStore represents an interface for manipulating peers.
|
|
|
|
type PeerStore interface {
|
2016-03-31 02:45:28 +02:00
|
|
|
// PutSeeder adds a seeder for the infoHash to the PeerStore.
|
2016-02-16 01:49:25 +01:00
|
|
|
PutSeeder(infoHash chihaya.InfoHash, p chihaya.Peer) error
|
2016-03-31 02:45:28 +02:00
|
|
|
// DeleteSeeder removes a seeder for the infoHash from the PeerStore.
|
2016-05-01 23:56:07 +02:00
|
|
|
//
|
|
|
|
// Returns ErrResourceDoesNotExist if the infoHash or peer does not
|
|
|
|
// exist.
|
2016-02-17 23:39:21 +01:00
|
|
|
DeleteSeeder(infoHash chihaya.InfoHash, p chihaya.Peer) error
|
2016-01-25 06:41:39 +01:00
|
|
|
|
2016-03-31 02:45:28 +02:00
|
|
|
// PutLeecher adds a leecher for the infoHash to the PeerStore.
|
2016-02-16 01:49:25 +01:00
|
|
|
PutLeecher(infoHash chihaya.InfoHash, p chihaya.Peer) error
|
2016-03-31 02:45:28 +02:00
|
|
|
// DeleteLeecher removes a leecher for the infoHash from the PeerStore.
|
2016-05-01 23:56:07 +02:00
|
|
|
//
|
|
|
|
// Returns ErrResourceDoesNotExist if the infoHash or peer does not
|
|
|
|
// exist.
|
2016-02-17 23:39:21 +01:00
|
|
|
DeleteLeecher(infoHash chihaya.InfoHash, p chihaya.Peer) error
|
2016-01-25 06:41:39 +01:00
|
|
|
|
2016-03-31 02:45:28 +02:00
|
|
|
// GraduateLeecher promotes a peer from a leecher to a seeder for the
|
|
|
|
// infoHash within the PeerStore.
|
2016-04-18 21:49:55 +02:00
|
|
|
//
|
|
|
|
// If the given Peer is not a leecher, it will still be added to the
|
|
|
|
// list of seeders and no error will be returned.
|
2016-02-16 01:49:25 +01:00
|
|
|
GraduateLeecher(infoHash chihaya.InfoHash, p chihaya.Peer) error
|
2016-04-18 21:49:55 +02:00
|
|
|
|
2016-03-31 02:45:28 +02:00
|
|
|
// AnnouncePeers returns a list of both IPv4, and IPv6 peers for an
|
|
|
|
// announce.
|
|
|
|
//
|
|
|
|
// If seeder is true then the peers returned will only be leechers, the
|
2016-05-01 23:56:07 +02:00
|
|
|
// ammount of leechers returned will be the smaller value of numWant or
|
|
|
|
// the available leechers.
|
2016-03-31 02:45:28 +02:00
|
|
|
// If it is false then seeders will be returned up until numWant or the
|
2016-05-01 23:56:07 +02:00
|
|
|
// available seeders, whichever is smaller. If the available seeders is
|
|
|
|
// less than numWant then peers are returned until numWant or they run out.
|
2016-04-12 18:06:32 +02:00
|
|
|
AnnouncePeers(infoHash chihaya.InfoHash, seeder bool, numWant int, peer4, peer6 chihaya.Peer) (peers, peers6 []chihaya.Peer, err error)
|
2016-03-31 02:45:28 +02:00
|
|
|
// CollectGarbage deletes peers from the peerStore which are older than the
|
|
|
|
// cutoff time.
|
2016-01-25 06:41:39 +01:00
|
|
|
CollectGarbage(cutoff time.Time) error
|
2016-03-31 02:45:28 +02:00
|
|
|
|
|
|
|
// GetSeeders gets all the seeders for a particular infoHash.
|
|
|
|
GetSeeders(infoHash chihaya.InfoHash) (peers, peers6 []chihaya.Peer, err error)
|
|
|
|
// GetLeechers gets all the leechers for a particular infoHash.
|
|
|
|
GetLeechers(infoHash chihaya.InfoHash) (peers, peers6 []chihaya.Peer, err error)
|
|
|
|
|
|
|
|
// NumSeeders gets the amount of seeders for a particular infoHash.
|
|
|
|
NumSeeders(infoHash chihaya.InfoHash) int
|
|
|
|
// NumLeechers gets the amount of leechers for a particular infoHash.
|
|
|
|
NumLeechers(infoHash chihaya.InfoHash) int
|
2016-06-19 18:49:43 +02:00
|
|
|
|
|
|
|
// Stopper provides the Stop method that stops the PeerStore.
|
|
|
|
// Stop should shut down the PeerStore in a separate goroutine and send
|
|
|
|
// an error to the channel if the shutdown failed. If the shutdown
|
|
|
|
// was successful, the channel is to be closed.
|
|
|
|
stopper.Stopper
|
2016-01-25 06:41:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// PeerStoreDriver represents an interface for creating a handle to the storage
|
|
|
|
// of peers.
|
|
|
|
type PeerStoreDriver interface {
|
2016-03-11 21:09:49 +01:00
|
|
|
New(*DriverConfig) (PeerStore, error)
|
2016-01-25 06:41:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// RegisterPeerStoreDriver makes a driver available by the provided name.
|
|
|
|
//
|
|
|
|
// If this function is called twice with the same name or if the driver is nil,
|
|
|
|
// it panics.
|
|
|
|
func RegisterPeerStoreDriver(name string, driver PeerStoreDriver) {
|
|
|
|
if driver == nil {
|
|
|
|
panic("storage: could not register nil PeerStoreDriver")
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, dup := peerStoreDrivers[name]; dup {
|
|
|
|
panic("storage: could not register duplicate PeerStoreDriver: " + name)
|
|
|
|
}
|
|
|
|
|
|
|
|
peerStoreDrivers[name] = driver
|
|
|
|
}
|
|
|
|
|
|
|
|
// OpenPeerStore returns a PeerStore specified by a configuration.
|
2016-03-11 21:09:49 +01:00
|
|
|
func OpenPeerStore(cfg *DriverConfig) (PeerStore, error) {
|
|
|
|
driver, ok := peerStoreDrivers[cfg.Name]
|
2016-01-25 06:41:39 +01:00
|
|
|
if !ok {
|
2016-03-11 21:12:43 +01:00
|
|
|
return nil, fmt.Errorf("storage: unknown PeerStoreDriver %q (forgotten import?)", cfg)
|
2016-01-25 06:41:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return driver.New(cfg)
|
|
|
|
}
|