// Broadcast calls an RPC on all of the peers in the Gateway's peer list. The // calls are run in parallel. Broadcasts are restricted to "one-way" RPCs, // which simply write an object and disconnect. This is why Broadcast takes an // interface{} instead of an RPCFunc. func (g *Gateway) Broadcast(name string, obj interface{}) { peers := g.Peers() g.log.Printf("INFO: broadcasting RPC \"%v\" to %v peers", name, len(peers)) // only encode obj once, instead of using WriteObject enc := encoding.Marshal(obj) fn := func(conn modules.PeerConn) error { return encoding.WritePrefix(conn, enc) } var wg sync.WaitGroup wg.Add(len(peers)) for _, addr := range peers { go func(addr modules.NetAddress) { err := g.RPC(addr, name, fn) if err != nil { // try one more time before giving up time.Sleep(10 * time.Second) g.RPC(addr, name, fn) } wg.Done() }(addr) } wg.Wait() }
// Broadcast calls an RPC on all of the specified peers. The calls are run in // parallel. Broadcasts are restricted to "one-way" RPCs, which simply write an // object and disconnect. This is why Broadcast takes an interface{} instead of // an RPCFunc. func (g *Gateway) Broadcast(name string, obj interface{}, peers []modules.Peer) { if g.threads.Add() != nil { return } defer g.threads.Done() g.log.Printf("INFO: broadcasting RPC %q to %v peers", name, len(peers)) // only encode obj once, instead of using WriteObject enc := encoding.Marshal(obj) fn := func(conn modules.PeerConn) error { return encoding.WritePrefix(conn, enc) } var wg sync.WaitGroup for _, p := range peers { wg.Add(1) go func(addr modules.NetAddress) { defer wg.Done() err := g.RPC(addr, name, fn) if err != nil { g.log.Debugf("WARN: broadcasting RPC %q to peer %q failed (attempting again in 10 seconds): %v", name, addr, err) // try one more time before giving up select { case <-time.After(10 * time.Second): case <-g.threads.StopChan(): return } err := g.RPC(addr, name, fn) if err != nil { g.log.Debugf("WARN: broadcasting RPC %q to peer %q failed twice: %v", name, addr, err) } } }(p.NetAddress) } wg.Wait() }
// MarshalSia implements the encoding.SiaMarshaler interface. It writes the // byte-slice representation of the Currency's internal big.Int to w. Note // that as the bytes of the big.Int correspond to the absolute value of the // integer, there is no way to marshal a negative Currency. func (c Currency) MarshalSia(w io.Writer) error { return encoding.WritePrefix(w, c.i.Bytes()) }