refactor(mtproto): sync redesign RPC replay ownership
This commit is contained in:
parent
7e0f9d1e62
commit
ac0566f779
28 changed files with 1304 additions and 343 deletions
|
|
@ -732,8 +732,8 @@ func preflightInboundItem(msgID int64, seqNo int32, typeID uint32, content bool,
|
|||
|
||||
// prepareInboundRPCBatch performs the whole container's count/byte admission
|
||||
// before copying or scheduling any API RPC. Capacity exhaustion is converted
|
||||
// into one consistent terminal FLOOD_WAIT result per uncached RPC; no business
|
||||
// handler from the batch is allowed to start in that case.
|
||||
// into one consistent local 500 WORKER_BUSY_TOO_LONG_RETRY result per uncached
|
||||
// RPC; no business handler from the batch is allowed to start in that case.
|
||||
func (s *Server) prepareInboundRPCBatch(ctx context.Context, c *Conn, plan *inboundPlan) error {
|
||||
if s.layerRPC != nil {
|
||||
return s.prepareInboundLayerRPCBatch(ctx, c, plan)
|
||||
|
|
@ -784,6 +784,13 @@ func (s *Server) prepareInboundRPCBatch(ctx context.Context, c *Conn, plan *inbo
|
|||
s.rpcRewrap.commit(candidate)
|
||||
item.kind = inboundItemReplayRPC
|
||||
item.payload = claim.encoded
|
||||
case rpcResultAcquireAcknowledged:
|
||||
// The client already ACKed the correlated rpc_result. Retire the
|
||||
// stale rewrap candidate and keep this duplicate ACK-only; neither
|
||||
// the old body nor the business handler may run again.
|
||||
s.rpcRewrap.commit(candidate)
|
||||
item.kind = inboundItemDuplicate
|
||||
item.payload = nil
|
||||
case rpcResultAcquirePending:
|
||||
s.rpcRewrap.commit(candidate)
|
||||
item.kind = inboundItemRewrappedRPC
|
||||
|
|
@ -847,6 +854,9 @@ func (s *Server) prepareInboundRPCBatch(ctx context.Context, c *Conn, plan *inbo
|
|||
)
|
||||
item.kind = inboundItemReplayRPC
|
||||
item.payload = claim.encoded
|
||||
case rpcResultAcquireAcknowledged:
|
||||
item.kind = inboundItemDuplicate
|
||||
item.payload = nil
|
||||
case rpcResultAcquirePending:
|
||||
// A malformed/replayed container may repeat the same msg_id after this
|
||||
// very plan installed its owner. More generally, any request already in
|
||||
|
|
@ -1026,6 +1036,10 @@ func (s *Server) executeInboundPlan(ctx context.Context, cs *connState, c *Conn,
|
|||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
// The key cannot reconnect to ACK or replay any old answer. Release every
|
||||
// logical outbox and receipt only after the terminal OK is physically on
|
||||
// the wire; retaining them for the offline TTL would be pure leakage.
|
||||
s.conns.ForgetLogicalSessionsForRawAuthKey(c.authKeyID)
|
||||
c.beginTerminalShutdown()
|
||||
c.closeTransport()
|
||||
return nil
|
||||
|
|
@ -1037,10 +1051,7 @@ func (s *Server) executeInboundPlan(ctx context.Context, cs *connState, c *Conn,
|
|||
if owner, _ := item.payload.(*rpcResultOwnerLease); owner != nil {
|
||||
owner.CompleteExecution(false)
|
||||
}
|
||||
if err := s.sendResult(ctx, c, item.msgID, &mt.RPCError{
|
||||
ErrorCode: 420,
|
||||
ErrorMessage: "FLOOD_WAIT_1",
|
||||
}); err != nil {
|
||||
if err := s.sendResult(ctx, c, item.msgID, rpcWorkerBusyError()); err != nil {
|
||||
return err
|
||||
}
|
||||
case inboundItemRPCAdmissionError:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue