func (r *rpcClient) stream(ctx context.Context, address string, req Request, opts CallOptions) (Streamer, error) { msg := &transport.Message{ Header: make(map[string]string), } md, ok := metadata.FromContext(ctx) if ok { for k, v := range md { msg.Header[k] = v } } // set timeout in nanoseconds msg.Header["Timeout"] = fmt.Sprintf("%d", opts.RequestTimeout) // set the content type for the request msg.Header["Content-Type"] = req.ContentType() cf, err := r.newCodec(req.ContentType()) if err != nil { return nil, errors.InternalServerError("go.micro.client", err.Error()) } c, err := r.opts.Transport.Dial(address, transport.WithStream(), transport.WithTimeout(opts.DialTimeout)) if err != nil { return nil, errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err)) } stream := &rpcStream{ context: ctx, request: req, closed: make(chan bool), codec: newRpcPlusCodec(msg, c, cf), } ch := make(chan error, 1) go func() { ch <- stream.Send(req.Request()) }() var grr error select { case err := <-ch: grr = err case <-ctx.Done(): grr = errors.New("go.micro.client", fmt.Sprintf("%v", ctx.Err()), 408) } if grr != nil { stream.Close() return nil, grr } return stream, nil }
func (r *rpcClient) stream(ctx context.Context, address string, req Request) (Streamer, error) { msg := &transport.Message{ Header: make(map[string]string), } md, ok := c.GetMetadata(ctx) if ok { for k, v := range md { msg.Header[k] = v } } msg.Header["Content-Type"] = req.ContentType() cf, err := r.newCodec(req.ContentType()) if err != nil { return nil, errors.InternalServerError("go.micro.client", err.Error()) } c, err := r.opts.Transport.Dial(address, transport.WithStream(), transport.WithTimeout(r.opts.DialTimeout)) if err != nil { return nil, errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err)) } var once sync.Once stream := &rpcStream{ context: ctx, request: req, once: once, closed: make(chan bool), codec: newRpcPlusCodec(msg, c, cf), } ch := make(chan error, 1) go func() { ch <- stream.Send(req.Request()) }() select { case err = <-ch: case <-time.After(r.opts.RequestTimeout): err = errors.New("go.micro.client", "request timeout", 408) } return stream, err }
func (r *rpcClient) call(ctx context.Context, address string, req Request, resp interface{}, opts CallOptions) error { msg := &transport.Message{ Header: make(map[string]string), } md, ok := metadata.FromContext(ctx) if ok { for k, v := range md { msg.Header[k] = v } } // set timeout in nanoseconds msg.Header["Timeout"] = fmt.Sprintf("%d", opts.RequestTimeout) // set the content type for the request msg.Header["Content-Type"] = req.ContentType() cf, err := r.newCodec(req.ContentType()) if err != nil { return errors.InternalServerError("go.micro.client", err.Error()) } var grr error c, err := r.pool.getConn(address, r.opts.Transport, transport.WithTimeout(opts.DialTimeout)) if err != nil { return errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err)) } defer func() { // defer execution of release r.pool.release(address, c, grr) }() stream := &rpcStream{ context: ctx, request: req, closed: make(chan bool), codec: newRpcPlusCodec(msg, c, cf), } defer stream.Close() ch := make(chan error, 1) go func() { defer func() { if r := recover(); r != nil { ch <- errors.InternalServerError("go.micro.client", "request error") } }() // send request if err := stream.Send(req.Request()); err != nil { ch <- err return } // recv request if err := stream.Recv(resp); err != nil { ch <- err return } // success ch <- nil }() select { case err := <-ch: grr = err return err case <-ctx.Done(): grr = ctx.Err() return errors.New("go.micro.client", fmt.Sprintf("%v", ctx.Err()), 408) } }