This repository has been archived by the owner on May 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
854 additions
and
656 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,94 @@ | ||
package dial | ||
|
||
import logging "github.com/ipfs/go-log" | ||
import ( | ||
"context" | ||
"fmt" | ||
"sync" | ||
) | ||
|
||
var log = logging.Logger("swarm/dialer") | ||
// Status represents the status of a Request or a Job. It is a bit array where each possible | ||
// status is represented by a bit, to enable efficient mask evaluation. | ||
type Status uint32 | ||
|
||
const ( | ||
// StatusInflight indicates that a request or job is currently making progress. | ||
StatusInflight Status = 1 << iota | ||
// StatusBlock indicates that a request or job is currently blocked, possibly as a | ||
// result of throttling or guarding. | ||
StatusBlocked | ||
// StatusCompleting indicates that a request or job has completed and its | ||
// callbacks are currently firing. | ||
StatusCompleting | ||
// StatusComplete indicates that a request or job has fully completed. | ||
StatusComplete | ||
) | ||
|
||
// internCallbackNames interns callback names, via the internedCallbackName function. | ||
var internCallbackNames = make(map[string]string) | ||
|
||
// Assert panics if the current status does not adhere to the specified bit mask. | ||
func (s *Status) Assert(mask Status) { | ||
if *s&mask == 0 { | ||
// it may be worth decoding the mask to a friendlier format. | ||
panic(fmt.Sprintf("illegal state %s; mask: %b", s, mask)) | ||
} | ||
} | ||
|
||
func (s Status) String() string { | ||
switch s { | ||
case StatusComplete: | ||
return "Status(Complete)" | ||
case StatusInflight: | ||
return "Status(Inflight)" | ||
case StatusCompleting: | ||
return "Status(Completing)" | ||
case StatusBlocked: | ||
return "Status(Blocked)" | ||
default: | ||
return fmt.Sprintf("Status(%d)", s) | ||
} | ||
} | ||
|
||
// internedCallbackName retrieves the interned string corresponding to this callback name. | ||
func internedCallbackName(name string) string { | ||
if n, ok := internCallbackNames[name]; ok { | ||
return n | ||
} | ||
internCallbackNames[name] = name | ||
return name | ||
} | ||
|
||
// contextHolder is a mixin that adds context tracking and mutation capabilities to another struct. | ||
type contextHolder struct { | ||
clk sync.RWMutex | ||
ctx context.Context | ||
cancels []context.CancelFunc | ||
} | ||
|
||
// UpdateContext updates the context and cancel functions atomically. | ||
func (ch *contextHolder) UpdateContext(mutator func(orig context.Context) (context.Context, context.CancelFunc)) { | ||
ch.clk.Lock() | ||
defer ch.clk.Unlock() | ||
|
||
ctx, cancel := mutator(ch.ctx) | ||
ch.ctx = ctx | ||
ch.cancels = append(ch.cancels, cancel) | ||
} | ||
|
||
// Context returns the context in a thread-safe manner. | ||
func (ch *contextHolder) Context() context.Context { | ||
ch.clk.RLock() | ||
defer ch.clk.RUnlock() | ||
|
||
return ch.ctx | ||
} | ||
|
||
// FireCancels invokes all cancel functions in the inverse order they were added. | ||
func (ch *contextHolder) FireCancels() { | ||
ch.clk.RLock() | ||
defer ch.clk.RUnlock() | ||
|
||
for i := len(ch.cancels) - 1; i >= 0; i-- { | ||
ch.cancels[i]() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Package dial contains the logic to establish outbound connections to other peers. In go lingo, that process is | ||
// called "dialing". | ||
// | ||
// The central component of this package is the dial Pipeline. A Pipeline assembles a set of modular components, | ||
// each with a clearly-delimited responsibility, into a dialing engine. Consumers can replace, delete, add components | ||
// to customize the dialing engine's behavior. | ||
// | ||
// The Pipeline comprises five components. We provide brief descriptions below. For more detail, refer to the | ||
// respective godocs of each interface: | ||
// | ||
// - Preparer: runs preparatory actions prior to the dial execution. Actions may include: deduplicating, populating | ||
// timeouts, circuit breaking, validating the peer ID, etc. | ||
// - AddressResolver: populates the set of addresses for a peer, either from the peerstore and/or from other sources, | ||
// such as a discovery process. | ||
// - Planner: schedules dials in time, responding to events from the environment, such as new addresses discovered, | ||
// or dial jobs completing. | ||
// - Throttler: throttles dials based on resource usage or other factors. | ||
// - Executor: actually carries out the network dials. | ||
// | ||
// This package provides basic implementations of all five dialer components, as well as a default Pipeline suitable | ||
// for simple host constructions. See the godocs on NewDefaultPipeline for details of the composition of the | ||
// default Pipeline. Note that the user can customize the Pipeline using the methods in that struct. | ||
// | ||
// These five components deal with two main entities: the Request and the Job. A Request represents a caller request | ||
// to dial a peer, identified by a peer ID. Along the execution of the Pipeline, the Request will translate into | ||
// one or many dial Jobs, each of which targets a multiaddr where that peer ID is presumably listening. | ||
package dial |
Oops, something went wrong.