func (s *Server) nextRequest() (func() error, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for s.ch != nil && s.inq.Len() == 0 {
		s.work.Wait()
	}
	if s.ch == nil && s.inq.Len() == 0 {
		return nil, s.err
	}
	ch := s.ch  
	next := s.inq.Remove(s.inq.Front()).(jmessages)
	s.log("Processing %d requests", len(next))
	return s.dispatch(next, ch), nil
}
nextRequest blocks until a request batch is available and returns a function
that dispatches it to the appropriate handlers. The result is only an error
if the connection failed; errors reported by the handler are reported to the
caller and not returned here.

The caller must invoke the returned function to complete the request.
package jrpc2
import (
	"container/list"
	"context"
	"encoding/json"
	"errors"
	"io"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/creachadair/jrpc2/channel"
	"github.com/creachadair/jrpc2/code"
	"github.com/creachadair/jrpc2/metrics"
	"golang.org/x/sync/semaphore"
)
type logger = func(string, ...interface{})
type Server struct {
	wg      sync.WaitGroup       
	mux     Assigner             
	sem     *semaphore.Weighted  
	allow1  bool                 
	allowP  bool                 
	log     logger               
	rpcLog  RPCLogger            
	dectx   decoder              
	ckreq   verifier             
	expctx  bool                 
	metrics *metrics.M           
	start   time.Time            
	builtin bool                 
	mu *sync.Mutex  
	nbar sync.WaitGroup   
	err  error            
	work *sync.Cond       
	inq  *list.List       
	ch   channel.Channel  
	used map[string]context.CancelFunc
	call   map[string]*Response
	callID int64
}
func NewServer(mux Assigner, opts *ServerOptions) *Server {
	if mux == nil {
		panic("nil assigner")
	}
	dc, exp := opts.decodeContext()
	s := &Server{
		mux:     mux,
		sem:     semaphore.NewWeighted(opts.concurrency()),
		allow1:  opts.allowV1(),
		allowP:  opts.allowPush(),
		log:     opts.logger(),
		rpcLog:  opts.rpcLog(),
		dectx:   dc,
		ckreq:   opts.checkRequest(),
		expctx:  exp,
		mu:      new(sync.Mutex),
		metrics: opts.metrics(),
		start:   opts.startTime(),
		builtin: opts.allowBuiltin(),
		inq:     list.New(),
		used:    make(map[string]context.CancelFunc),
		call:    make(map[string]*Response),
		callID:  1,
	}
	s.work = sync.NewCond(s.mu)
	return s
}
func (s *Server) Start(c channel.Channel) *Server {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.ch != nil {
		panic("server is already running")
	}
	s.ch = c
	if s.start.IsZero() {
		s.start = time.Now().In(time.UTC)
	}
	s.err = nil
	s.wg.Add(2)
	go func() { defer s.wg.Done(); s.read(c) }()
	go func() { defer s.wg.Done(); s.serve() }()
	return s
}
func (s *Server) serve() {
	for {
		next, err := s.nextRequest()
		if err != nil {
			s.log("Reading next request: %v", err)
			return
		}
		s.wg.Add(1)
		go func() {
			defer s.wg.Done()
			next()
		}()
	}
}