Example #1
0
func (r *RPC) openNewClient() {
	ci, err := jsonrpc.Dial(r.network, r.dstServer, r.OnBrokenConnection)
	if err != nil {
		r.closeIfOpenNumZero(err)
		return
	}

	r.mu.Lock()
	defer r.mu.Unlock()

	if r.closed {
		ci.Close()
		return
	}
}
Example #2
0
// return a connection(from idle conn lists or newly created) for rpc use
func (r *RPC) getConn() (nc *conn, err error) {
	fmt.Printf("myrpc.RPC.getConn start:r(%+v)\n", *r)
	defer func() { fmt.Printf("myrpc.RPC.getConn end:r(%+v),err(%+v)\n", *r, err) }()
	r.mu.Lock()
	if r.closed {
		r.mu.Unlock()
		return nil, errRPCClosed
	}

	if r.maxOpen > 0 && r.numOpen >= r.maxOpen && len(r.freeConn) == 0 {
		// wait a free conn
		req := make(chan connRequest, 1)
		r.connRequests = append(r.connRequests, req)
		r.mu.Unlock()
		ret := <-req
		return ret.rc, ret.err
	}

	for c := len(r.freeConn); c > 0; {
		// get one from freeConn list
		ci := r.freeConn[0]
		r.freeConn = r.freeConn[1:]
		fmt.Printf("myrpc.RPC.getConn get from r.freeConn:ci(%+v)\n", *ci)

		// check if ci is closed already
		if ci.isClosed() {
			ci.Close() // Todo:close conn in r.mu.Unlock sucks, but is right here
			r.numOpen--
			c = len(r.freeConn)
			continue
		}

		ci.inUse = true
		r.mu.Unlock()
		return ci, nil
	}

	// create a new connection
	r.numOpen++
	r.mu.Unlock()
	ci, err := jsonrpc.Dial(r.network, r.dstServer, r.OnBrokenConnection)
	if err != nil {
		r.mu.Lock()
		r.numOpen--
		r.mu.Unlock()
		// new creation failed, close if qualified
		r.closeIfOpenNumZero(err)
		return nil, err
	}
	fmt.Printf("myrpc.RPC.getConn create a new connection:r(%p),*r(%+v)\n", r, *r)

	r.mu.Lock()
	rc := &conn{
		r:  r,
		ci: ci,
	}
	rc.inUse = true
	r.mu.Unlock()

	return rc, nil
}