Beispiel #1
0
// send is the synchronous variant of SendAsync
func (acl *APIClient) send(req *wire.Request) (resp *wire.Response, err error) {
	// `0` is reserved for broadcast counters,
	// increment first therefore.
	acl.idcnt++
	req.ID = acl.idcnt

	done := make(chan util.Empty)
	err = acl.cnv.SendAsync(req, func(respIn *wire.Response) {
		resp = respIn
		done <- util.Empty{}
	})

	// TODO: Make that configurable?
	timer := time.NewTimer(10 * time.Second)

	// Wait until we got a response from SendAsync or until
	// we time out.
	select {
	case <-done:
		break
	case stamp := <-timer.C:
		log.Warningf("APIClient operation timed out at %v", stamp)
		return nil, util.ErrTimeout
	}

	return
}
Beispiel #2
0
// broadcast implements the actual network broadcasting.
// It just sends the request over all conversations in the pool.
func (cn *Connector) broadcast(req *wire.Request) error {
	var errs util.Errors

	req.ID = 0

	for cnv := range cn.cp.Iter() {
		if err := cnv.SendAsync(req, nil); err != nil {
			errs = append(errs, err)
		}
	}

	return errs.ToErr()
}
Beispiel #3
0
// SendAsync sends `req` to the other end and calls callback on the response.
func (cnv *Conversation) SendAsync(req *wire.Request, callback transfer.AsyncFunc) error {
	cnv.Lock()
	defer cnv.Unlock()

	// Add a nonce so that the same message is guaranteed to result
	// in a different ciphertext:
	req.Nonce = rand.Int63()

	// Broadcast messages usually do not register a callback.
	// (it wouldn't have been called anyways)
	if callback != nil {
		cnv.notifees[req.ID] = callback
	}

	return cnv.proto.Send(req)
}