MCPcopy Create free account
hub / github.com/CPChain/chain / serveRequest

Method serveRequest

api/rpc/server.go:128–212  ·  view source on GitHub ↗

serveRequest will reads requests from the codec, calls the RPC callback and writes the response to the given codec. If singleShot is true it will process a single request, otherwise it will handle requests until the codec returns an error when reading a request (in most cases an EOF). It executes r

(ctx context.Context, codec ServerCodec, singleShot bool, options CodecOption)

Source from the content-addressed store, hash-verified

126// requests until the codec returns an error when reading a request (in most cases
127// an EOF). It executes requests in parallel when singleShot is false.
128func (s *Server) serveRequest(ctx context.Context, codec ServerCodec, singleShot bool, options CodecOption) error {
129 var pend sync.WaitGroup
130
131 defer func() {
132 if err := recover(); err != nil {
133 const size = 64 << 10
134 buf := make([]byte, size)
135 buf = buf[:runtime.Stack(buf, false)]
136 log.Error(string(buf))
137 }
138 s.codecsMu.Lock()
139 s.codecs.Remove(codec)
140 s.codecsMu.Unlock()
141 }()
142
143 // ctx, cancel := context.WithCancel(context.Background())
144 ctx, cancel := context.WithCancel(ctx)
145 defer cancel()
146
147 // if the codec supports notification include a notifier that callbacks can use
148 // to send notification to clients. It is tied to the codec/connection. If the
149 // connection is closed the notifier will stop and cancels all active subscriptions.
150 if options&OptionSubscriptions == OptionSubscriptions {
151 ctx = context.WithValue(ctx, notifierKey{}, newNotifier(codec))
152 }
153 s.codecsMu.Lock()
154 if atomic.LoadInt32(&s.run) != 1 { // server stopped
155 s.codecsMu.Unlock()
156 return &shutdownError{}
157 }
158 s.codecs.Add(codec)
159 s.codecsMu.Unlock()
160
161 // test if the server is ordered to stop
162 for atomic.LoadInt32(&s.run) == 1 {
163 reqs, batch, err := s.readRequest(codec)
164 if err != nil {
165 // If a parsing error occurred, send an error
166 if err.Error() != "EOF" {
167 log.Debug(fmt.Sprintf("read error %v\n", err))
168 codec.Write(codec.CreateErrorResponse(nil, err))
169 }
170 // Error or end of stream, wait for requests and tear down
171 pend.Wait()
172 return nil
173 }
174
175 // check if server is ordered to shutdown and return an error
176 // telling the client that his request failed.
177 if atomic.LoadInt32(&s.run) != 1 {
178 err = &shutdownError{}
179 if batch {
180 resps := make([]interface{}, len(reqs))
181 for i, r := range reqs {
182 resps[i] = codec.CreateErrorResponse(&r.id, err)
183 }
184 codec.Write(resps)
185 } else {

Callers 2

ServeCodecMethod · 0.95
ServeSingleRequestMethod · 0.95

Calls 13

readRequestMethod · 0.95
execBatchMethod · 0.95
execMethod · 0.95
newNotifierFunction · 0.85
LockMethod · 0.80
UnlockMethod · 0.80
DebugMethod · 0.80
WaitMethod · 0.80
ErrorMethod · 0.65
AddMethod · 0.65
WriteMethod · 0.65
CreateErrorResponseMethod · 0.65

Tested by

no test coverage detected