Closed ripplek closed 2 years ago
Thanks for opening this @ripplek. After looking through your call stack and the code you provided I am certain that this is not a bug in grpc-swift.
The precondition that is being triggered asserts that the a call to the ClientInterceptorContext.receive()
is on the correct event loop. This is happening because you are spawning Task
and calling the context.receive
method inside the task here:
Task {
switch await refreshTokenReq.result {
case .success:
updateMetadataRetry()
case .failure:
context.receive(part)
}
}
When you create a new Task
the content inside the task is executed on one of the threads of the cooperative thread pool.
I would advise you to be careful with mixing NIO EventLoop
based APIs and Swift Concurrency APIs. What you are trying to achieve is probably better rewritten completely using EventLoopFuture
s.
If you still want to go down the route of mixing the two concepts you need to think carefully on which thread you are executing and make the necessary thread jumps back to the EventLoop
by calling something like eventLoop.execute {}
. However, this can introduce data races quite easily so be extra careful!
@FranzBusch is absolutely right here: the send
/receive
methods on the interceptor context must be called from the appropriate eventLoop
. This precondition is in place to make sure that the API is used correctly.
Hello @FranzBusch @glbrntt, Thanks for your reply, I updated my code and tested
Test A
if let refreshTokenReq = tokenRequestCache[requestToken] {
Task {
switch await refreshTokenReq.result {
case .success:
context.eventLoop.execute {
updateMetadataRetry()
}
case .failure:
context.eventLoop.execute {
context.receive(part)
}
}
}
return
}
tokenRequestCache[requestToken] = Task<App_RefreshTokensReply, Error> {
do {
let reply = try await App_AccountAsyncClient(channel: self.client.channel)
.refreshTokens(.with { $0.refreshToken = APICommon.refreshToken })
APICommon.accessToken = reply.accessToken
APICommon.refreshToken = reply.refreshToken
context.eventLoop.execute {
updateMetadataRetry()
}
log.warning("refresh token success: \(reply)")
return reply
} catch {
log.error("refresh token failed: \(error)")
tokenRequestCache[requestToken] = nil
context.eventLoop.execute {
context.receive(part)
}
throw error
}
}
Test B
@Sendable func updateMetadataRetry() {
// We know how to handle this: make a new call.
let call: Call<Request, Response> = self.client.channel.makeCall(
path: context.path,
type: context.type,
callOptions: context.options,
// We could grab interceptors from the client, but we don't need to.
interceptors: []
)
// We're retying the call now.
self.state = .retrying(call)
// Invoke the call and redirect responses here.
call.invoke { error in
if context.eventLoop.inEventLoop {
context.errorCaught(error)
} else {
context.eventLoop.execute {
context.errorCaught(error)
}
}
} onResponsePart: { part in
if context.eventLoop.inEventLoop {
context.receive(part)
} else {
context.eventLoop.execute {
context.receive(part)
}
}
}
var newParts = parts
// Parts must contain the metadata as the first item if we got that first response.
if case var .some(.metadata(metadata)) = parts.first {
metadata.replaceOrAdd(name: "access_token", value: APICommon.accessToken)
newParts[0] = .metadata(metadata)
}
// Now replay any requests on the retry call.
for part in newParts {
call.send(part, promise: nil)
}
}
Test B finally solved my problem, This is my final revision
@Sendable func updateMetadataRetry() {
// We know how to handle this: make a new call.
let call: Call<Request, Response> = self.client.channel.makeCall(
path: context.path,
type: context.type,
callOptions: context.options,
// We could grab interceptors from the client, but we don't need to.
interceptors: []
)
// We're retying the call now.
self.state = .retrying(call)
// Invoke the call and redirect responses here.
call.invoke { error in
if context.eventLoop.inEventLoop {
context.errorCaught(error)
} else {
context.eventLoop.execute {
context.errorCaught(error)
}
}
} onResponsePart: { part in
if context.eventLoop.inEventLoop {
context.receive(part)
} else {
context.eventLoop.execute {
context.receive(part)
}
}
}
var newParts = parts
// Parts must contain the metadata as the first item if we got that first response.
if case var .some(.metadata(metadata)) = parts.first {
metadata.replaceOrAdd(name: "access_token", value: APICommon.accessToken)
newParts[0] = .metadata(metadata)
}
// Now replay any requests on the retry call.
for part in newParts {
call.send(part, promise: nil)
}
}
if let refreshTokenReq = tokenRequestCache[requestToken] {
Task {
switch await refreshTokenReq.result {
case .success:
updateMetadataRetry()
case .failure:
context.eventLoop.execute {
context.receive(part)
}
}
}
return
}
tokenRequestCache[requestToken] = Task<App_RefreshTokensReply, Error> {
do {
let reply = try await App_AccountAsyncClient(channel: self.client.channel)
.refreshTokens(.with { $0.refreshToken = APICommon.refreshToken })
APICommon.accessToken = reply.accessToken
APICommon.refreshToken = reply.refreshToken
updateMetadataRetry()
log.warning("refresh token success: \(reply)")
return reply
} catch {
log.error("refresh token failed: \(error)")
tokenRequestCache[requestToken] = nil
context.eventLoop.execute {
context.receive(part)
}
throw error
}
}
Describe the bug
pod 'gRPC-Swift', :git => 'https://github.com/grpc/grpc-swift.git', :branch => '1.7.1-async-await'
GRPCChannel
let channel = try GRPCChannelPool.with( target: .hostAndPort(host, Int(port)), transportSecurity: .plaintext, eventLoopGroup: NIOTSEventLoopGroup(loopCount: 5, defaultQoS: .default) ) { // Configure keepalive. $0.keepalive = keepalive $0.backgroundActivityLogger = channelLogger } return channel
below is my testcase
sometimes the testcase crash in
call.invoke(onError: context.errorCaught(_:), onResponsePart: context.receive(_:))
`
Additional information
Test Suite 'Selected tests' started at 2022-05-25 11:28:02.229 Test Suite 'RobotSDKTests.xctest' started at 2022-05-25 11:28:02.230 Test Suite 'RbotTests' started at 2022-05-25 11:28:02.230 Test Case '-[RobotSDKTests.RbotTests testGenerateBindRobotQRCode]' started. 2022-05-25 11:28:02.288753+0800 RobotSDK[87525:1909802] [] nw_listener_socket_inbox_create_socket setsockopt SO_NECP_LISTENUUID failed [2: No such file or directory] 2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] PoolManager.swift:172 initialize(perPoolConfiguration:logger:) : poolmanager.pools.waiters_per_pool=100 poolmanager.pools.conns_per_pool=1 poolmanager.pools.count=5 poolmanager.id=ObjectIdentifier(0x0000600003857e00) initializing connection pool manager
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [💚 DEBUG] ConnectionPool.swift:370 _enqueueWaiter(deadline:promise:logger:initializer:) : grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 pool.waiters.count=0 pool.waiter.id=ObjectIdentifier(0x0000600000e26800) waiting for a connection to become available
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [🖤 TRACE] ConnectionPool.swift:378 _enqueueWaiter(deadline:promise:logger:initializer:) : poolmanager.id=ObjectIdentifier(0x0000600003857e00) pool.waiters.count=1 enqueued connection waiter
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] ConnectionPool.swift:426 _shouldBringUpAnotherConnection() : pool.reservations.loadThreshold=0.9 poolmanager.id=ObjectIdentifier(0x0000600003857e00) pool.reservations.count=1 pool.reservations.capacity=0 pool.reservations.load=inf stream reservation load factor greater than or equal to threshold, bringing up additional connection if available
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:195 send(_:promise:context:) : > Starting '/app.Account/BindThirdAccount' RPC, headers: ['authorization': 'Robot', 'access_token': '74']
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:853 buffer(_:promise:) : request_part=metadata grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 call_state=awaitingTransport (0 parts buffered) buffering request part
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:200 send(_:promise:context:) : > Sending request with 'RobotSDK.App_BindThirdAccountRequest: thirdAccount: "kun.zhang@voidtech.com.cn" plat: IOS '
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:853 buffer(_:promise:) : grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 request_part=message call_state=awaitingTransport (1 parts buffered) buffering request part
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:204 send(_:promise:context:) : > Closing request stream
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:853 buffer(_:promise:) : grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 request_part=end call_state=awaitingTransport (2 parts buffered) buffering request part
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] PlatformSupport.swift:199 makeClientBootstrap(group:logger:) : poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 making client bootstrap with event loop group of type NIOTSEventLoop
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] PlatformSupport.swift:203 makeClientBootstrap(group:logger:) : poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 Network.framework is available and the EventLoopGroup is compatible with NIOTS, creating a NIOTSConnectionBootstrap
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] ConnectionManager.swift:621 channelActive(channel:multiplexer:) : poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 connectivity_state=connecting activating connection
11:28:02.330 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:499 receiveSettings(_:): HTTP2 settings update { grpc_connection_id=848AF8C4-0DA4-4D40-A198-FC83A76BA6BD h2_settings_initial_window_size=8388608 h2_settings_max_concurrent_streams=0 h2_settings_max_frame_size=8388608 h2_settings_max_header_listsize=16384 } 2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:499 receiveSettings(:) : h2_settings_initial_window_size=8388608 h2_settings_max_concurrent_streams=100 grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 grpc.conn.addr_local=::1 h2_settings_max_frame_size=16384 h2_settings_max_header_list_size=16384 grpc.conn.addr_remote=::1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) HTTP2 settings update
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] ConnectionManager.swift:743 ready() : poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 connectivity_state=active connection ready
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [🖤 TRACE] ConnectionPool.swift:661 tryServiceWaiters() : pool.waiters.count=1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) servicing waiters
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [🖤 TRACE] ConnectionPool.swift:687 tryServiceWaiters() : poolmanager.id=ObjectIdentifier(0x0000600003857e00) pool.waiters.count=0 pool.waiters.serviced=1 done servicing waiters
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [💚 DEBUG] ClientTransport.swift:333 _transportActivated(channel:) : grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 grpc.conn.addr_remote=::1 grpc.conn.addr_local=::1 activated stream channel
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:871 unbuffer() : request_parts=3 grpc.conn.addr_remote=::1 grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 grpc.conn.addr_local=::1 unbuffering request parts
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:881 unbuffer() : request_part=metadata grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 unbuffering request part
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:509 write(context:data:promise:) : h2_headers=[([], ":method", "POST"), ([], ":path", "/app.Account/BindThirdAccount"), ([], ":authority", "localhost"), ([], ":scheme", "http"), ([], "content-type", "application/grpc"), ([], "te", "trailers"), ([], "grpc-timeout", "19999881u"), ([], "authorization", "Robot"), ([], "access_token", "74"), ([], "user-agent", "grpc-swift-nio/1.7.1-async-await.1")] h2_payload=HEADERS grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 h2_end_stream=false writing HTTP2 frame
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:881 unbuffer() : grpc.conn.addr_remote=::1 grpc.conn.addr_local=::1 request_part=message grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 unbuffering request part
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:536 write(context:data:promise:) : h2_data_bytes=34 h2_end_stream=false grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 h2_payload=DATA writing HTTP2 frame
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:881 unbuffer() : grpc.conn.addr_local=::1 request_part=end grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 grpc.conn.addr_remote=::1 unbuffering request part
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:569 write(context:data:promise:) : h2_payload=DATA h2_end_stream=true h2_data_bytes=0 grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 writing HTTP2 frame
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:646 streamCreated(_:logger:) : h2_active_streams=1 grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 h2_stream_id=HTTP2StreamID(1) HTTP2 stream created
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:900 unbuffer() : grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 grpc.conn.addr_remote=::1 grpc.conn.addr_local=::1 request buffer drained
11:28:02.384 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:646 streamCreated(_:logger:): HTTP2 stream created { grpc_connection_id=848AF8C4-0DA4-4D40-A198-FC83A76BA6BD h2_active_streams=1 h2_stream_id=HTTP2StreamID(1) } 2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:355 readHeaders(content:context:) : grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 h2_payload=HEADERS h2_end_stream=false h2_headers=[([], ":status", "200"), ([], "content-type", "application/grpc")] received HTTP2 frame
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:226 receive(_:context:) : < Received headers: [':status': '200', 'content-type': 'application/grpc']
11:28:02.388 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:668 streamClosed(_:logger:): HTTP2 stream closed { grpc_connection_id=848AF8C4-0DA4-4D40-A198-FC83A76BA6BD h2_active_streams=0 h2_stream_id=HTTP2StreamID(1) } 2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:429 readData(content:context:) : h2_payload=DATA h2_data_bytes=5 h2_end_stream=false grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 received HTTP2 frame
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:232 receive(_:context:) : < Received response with 'RobotSDK.App_BindThirdAccountReply: '
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:668 streamClosed(_:logger:) : h2_active_streams=0 grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 h2_stream_id=HTTP2StreamID(1) HTTP2 stream closed
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:355 readHeaders(content:context:) : grpc_request_id=208A5FE4-CAAC-4E34-BACC-AF0E4BEC2A28 h2_end_stream=true h2_headers=[([], "grpc-status", "0")] h2_payload=HEADERS received HTTP2 frame
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:239 receive(_:context:) : < Response stream closed /app.Account/BindThirdAccount with status: 'ok (0)' and trailers: ['grpc-status': '0']
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [💚 DEBUG] ClientTransport.swift:333 _transportActivated(channel:) : grpc.conn.addr_remote=::1 grpc.conn.addr_local=::1 grpc_request_id=14F90D4D-B361-4F3C-B0C4-9765E8C51A79 activated stream channel
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:871 unbuffer() : request_parts=0 grpc.conn.addr_remote=::1 grpc.conn.addr_local=::1 grpc_request_id=14F90D4D-B361-4F3C-B0C4-9765E8C51A79 unbuffering request parts
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:900 unbuffer() : grpc.conn.addr_remote=::1 grpc.conn.addr_local=::1 grpc_request_id=14F90D4D-B361-4F3C-B0C4-9765E8C51A79 request buffer drained
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:195 send(_:promise:context:) : > Starting '/app.Robot/BindMachine' RPC, headers: ['authorization': 'Robot', 'access_token': '74']
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:509 write(context:data:promise:) : h2_headers=[([], ":method", "POST"), ([], ":path", "/app.Robot/BindMachine"), ([], ":authority", "localhost"), ([], ":scheme", "http"), ([], "content-type", "application/grpc"), ([], "te", "trailers"), ([], "grpc-timeout", "19999971u"), ([], "authorization", "Robot"), ([], "access_token", "74"), ([], "user-agent", "grpc-swift-nio/1.7.1-async-await.1")] grpc_request_id=14F90D4D-B361-4F3C-B0C4-9765E8C51A79 h2_payload=HEADERS h2_end_stream=false writing HTTP2 frame
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:200 send(_:promise:context:) : > Sending request with 'RobotSDK.App_BindMachineRequest: machineModel: "Rbot_air" '
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:536 write(context:data:promise:) : grpc_request_id=14F90D4D-B361-4F3C-B0C4-9765E8C51A79 h2_payload=DATA h2_data_bytes=14 h2_end_stream=false writing HTTP2 frame
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:204 send(_:promise:context:) : > Closing request stream
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:569 write(context:data:promise:) : h2_payload=DATA grpc_request_id=14F90D4D-B361-4F3C-B0C4-9765E8C51A79 h2_data_bytes=0 h2_end_stream=true writing HTTP2 frame
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:646 streamCreated(_:logger:) : h2_active_streams=1 grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 h2_stream_id=HTTP2StreamID(3) HTTP2 stream created
11:28:02.399 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:646 streamCreated(_:logger:): HTTP2 stream created { grpc_connection_id=848AF8C4-0DA4-4D40-A198-FC83A76BA6BD h2_active_streams=1 h2_streamid=HTTP2StreamID(3) } 11:28:02.401 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:668 streamClosed(:logger:): HTTP2 stream closed { grpc_connection_id=848AF8C4-0DA4-4D40-A198-FC83A76BA6BD h2_active_streams=0 h2_streamid=HTTP2StreamID(3) } 2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:668 streamClosed(:logger:) : h2_active_streams=0 grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 h2_stream_id=HTTP2StreamID(3) HTTP2 stream closed
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:355 readHeaders(content:context:) : grpc_request_id=14F90D4D-B361-4F3C-B0C4-9765E8C51A79 h2_payload=HEADERS h2_headers=[([], ":status", "200"), ([], "content-type", "application/grpc"), ([], "grpc-status", "16"), ([], "www-authenticate", "Robot")] h2_end_stream=true received HTTP2 frame
2022-05-25T11:28:02+0800 [Robot] [💛 WARNING] Interceptors.swift:241 receive(_:context:) : < Response stream closed /app.Robot/BindMachine with status: 'unauthenticated (16)' and trailers: [':status': '200', 'content-type': 'application/grpc', 'grpc-status': '16', 'www-authenticate': 'Robot']
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:195 send(_:promise:context:) : > Starting '/app.Account/RefreshTokens' RPC, headers: ['authorization': 'Robot', 'access_token': '74']
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:200 send(_:promise:context:) : > Sending request with 'RobotSDK.App_RefreshTokensRequest: refreshToken: "cGBMje7F40wt6VL3HVtAjfXtLqZL+yukF/xSr6PdaZre2Yt/jf5fFtjLCAM5nayuCXqv6RayZFzCVSGPZ14R/XK2+aodYBDHE+jgNWyK5yhRctH+AE5bnnybSc6dNmT2F2cWa1ihjwZ5/zodk2+hrzhgxe1m6ZLZxh4ZacK4SMYZ299SKcJPpoSPJ5AxYDjkUVlWT3hqOiJ9Rlr7x68VvpjXvJwy6rbcZtko+qO1bNyNfzdXO4Cw31ldXhtAvZYwmilIut7yKMt37Qd88t7xaDU=.bba0955e42054885f5d908a14138957a97520abd38d6036dd6a588c052f42b5c.V2" '
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:204 send(_:promise:context:) : > Closing request stream
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:646 streamCreated(_:logger:) : h2_active_streams=1 grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 h2_stream_id=HTTP2StreamID(5) HTTP2 stream created
11:28:02.410 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:646 streamCreated(_:logger:): HTTP2 stream created { grpc_connection_id=848AF8C4-0DA4-4D40-A198-FC83A76BA6BD h2_active_streams=1 h2_streamid=HTTP2StreamID(5) } 2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:226 receive(:context:) : < Received headers: [':status': '200', 'content-type': 'application/grpc']
11:28:02.412 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:668 streamClosed(_:logger:): HTTP2 stream closed { grpc_connection_id=848AF8C4-0DA4-4D40-A198-FC83A76BA6BD h2_active_streams=0 h2_streamid=HTTP2StreamID(5) } 2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:232 receive(:context:) : < Received response with 'RobotSDK.App_RefreshTokensReply: error { msg: "success" } accessToken: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInZlcnNpb24iOiIyIn0=.eyJzZXNzaW9uSGFuZGxlIjoiMzk3YjZmNGYtNmYwZi00NGRjLWFhMzMtMjljMDcwMGI2MmEyIiwidXNlcklkIjoiT2JqZWN0SUQoXCI2Mjg0YTI2NTZlZWZmMDQ1ZTg2MzE5MWNcIikiLCJyZWZyZXNoVG9rZW5IYXNoMSI6IjQxYWVjZTNjN2FiOGQ1NzdkODc1MDg5MzgwY2Y5YjdmNDYyYTc3NDcxMGQ2NDlmOGNjYmZiYzJhZWNkMjY5MjMiLCJ1c2VyRGF0YSI6e30sImV4cGlyeVRpbWUiOjE2NTI5NzQ2NTE3NDUsInRpbWVDcmVhdGVkIjoxNjUyOTMxNDUxNzQ1LCJsbXJ0IjoxNjUyOTMxNDUxNzQ1fQ==.poq41KmXxE9ux4lgjIofwqpXI+N2aYakrKuf7/Y4WHMBStDfNURxQYHN58Kx84iCbLlGigz7ENpE4oLiLktPxnNeS2zSFxkpmW1QY2hnNDsOT4E7gNBL3YyOoSBVIsc+k9gIFkczCxqY2gjwzUTiQZvGfh1JSmP3EIYvF25uETPIYKlerWffNF4uKU5E77/OF3B+qEoobh6NYs4/TQQ3hKl475OAYMLva7jnw8qGeHwGSDPksO08M1feKH8mOURbANU1NQkI3jMk9AuyGtlbOgloACv9I38IlsGtzHwyoDE9eTSRBxrAoq/Ouy/7b37sIm0PC2tucssqWRwKzxGJMA==" refreshToken: "cGBMje7F40wt6VL3HVtAjfXtLqZL+yukF/xSr6PdaZre2Yt/jf5fFtjLCAM5nayuCXqv6RayZFzCVSGPZ14R/XK2+aodYBDHE+jgNWyK5yhRctH+AE5bnnybSc6dNmT2F2cWa1ihjwZ5/zodk2+hrzhgxe1m6ZLZxh4ZacK4SMYZ299SKcJPpoSPJ5AxYDjkUVlWT3hqOiJ9Rlr7x68VvpjXvJwy6rbcZtko+qO1bNyNfzdXO4Cw31ldXhtAvZYwmilIut7yKMt37Qd88t7xaDU=.bba0955e42054885f5d908a14138957a97520abd38d6036dd6a588c052f42b5c.V2" '
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [💚 DEBUG] Call.swift:123 invoke(onError:onResponsePart:) : grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 path=/app.Robot/BindMachine starting rpc
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [💚 DEBUG] ConnectionPool.swift:370 _enqueueWaiter(deadline:promise:logger:initializer:) : pool.waiter.id=ObjectIdentifier(0x0000600000e2d9a0) pool.waiters.count=0 grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 waiting for a connection to become available
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [🖤 TRACE] ConnectionPool.swift:378 _enqueueWaiter(deadline:promise:logger:initializer:) : poolmanager.id=ObjectIdentifier(0x0000600003857e00) pool.waiters.count=1 enqueued connection waiter
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:668 streamClosed(_:logger:) : h2_stream_id=HTTP2StreamID(5) grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=DC02ADC5-4B0E-42CE-A51B-491018C8987A/0 h2_active_streams=0 HTTP2 stream closed
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] ConnectionPool.swift:426 _shouldBringUpAnotherConnection() : pool.reservations.count=1 pool.reservations.load=inf pool.reservations.capacity=0 poolmanager.id=ObjectIdentifier(0x0000600003857e00) pool.reservations.loadThreshold=0.9 stream reservation load factor greater than or equal to threshold, bringing up additional connection if available
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:239 receive(_:context:) : < Response stream closed /app.Account/RefreshTokens with status: 'ok (0)' and trailers: ['grpc-status': '0']
2022-05-25T11:28:02+0800 [Robot] [💛 WARNING] Interceptors.swift:152 receive(_:context:) : refresh token success: RobotSDK.App_RefreshTokensReply: error { msg: "success" } accessToken: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInZlcnNpb24iOiIyIn0=.eyJzZXNzaW9uSGFuZGxlIjoiMzk3YjZmNGYtNmYwZi00NGRjLWFhMzMtMjljMDcwMGI2MmEyIiwidXNlcklkIjoiT2JqZWN0SUQoXCI2Mjg0YTI2NTZlZWZmMDQ1ZTg2MzE5MWNcIikiLCJyZWZyZXNoVG9rZW5IYXNoMSI6IjQxYWVjZTNjN2FiOGQ1NzdkODc1MDg5MzgwY2Y5YjdmNDYyYTc3NDcxMGQ2NDlmOGNjYmZiYzJhZWNkMjY5MjMiLCJ1c2VyRGF0YSI6e30sImV4cGlyeVRpbWUiOjE2NTI5NzQ2NTE3NDUsInRpbWVDcmVhdGVkIjoxNjUyOTMxNDUxNzQ1LCJsbXJ0IjoxNjUyOTMxNDUxNzQ1fQ==.poq41KmXxE9ux4lgjIofwqpXI+N2aYakrKuf7/Y4WHMBStDfNURxQYHN58Kx84iCbLlGigz7ENpE4oLiLktPxnNeS2zSFxkpmW1QY2hnNDsOT4E7gNBL3YyOoSBVIsc+k9gIFkczCxqY2gjwzUTiQZvGfh1JSmP3EIYvF25uETPIYKlerWffNF4uKU5E77/OF3B+qEoobh6NYs4/TQQ3hKl475OAYMLva7jnw8qGeHwGSDPksO08M1feKH8mOURbANU1NQkI3jMk9AuyGtlbOgloACv9I38IlsGtzHwyoDE9eTSRBxrAoq/Ouy/7b37sIm0PC2tucssqWRwKzxGJMA==" refreshToken: "cGBMje7F40wt6VL3HVtAjfXtLqZL+yukF/xSr6PdaZre2Yt/jf5fFtjLCAM5nayuCXqv6RayZFzCVSGPZ14R/XK2+aodYBDHE+jgNWyK5yhRctH+AE5bnnybSc6dNmT2F2cWa1ihjwZ5/zodk2+hrzhgxe1m6ZLZxh4ZacK4SMYZ299SKcJPpoSPJ5AxYDjkUVlWT3hqOiJ9Rlr7x68VvpjXvJwy6rbcZtko+qO1bNyNfzdXO4Cw31ldXhtAvZYwmilIut7yKMt37Qd88t7xaDU=.bba0955e42054885f5d908a14138957a97520abd38d6036dd6a588c052f42b5c.V2"
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:195 send(_:promise:context:) : > Starting '/app.Robot/BindMachine' RPC, headers: ['authorization': 'Robot', 'access_token': 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInZlcnNpb24iOiIyIn0=.eyJzZXNzaW9uSGFuZGxlIjoiMzk3YjZmNGYtNmYwZi00NGRjLWFhMzMtMjljMDcwMGI2MmEyIiwidXNlcklkIjoiT2JqZWN0SUQoXCI2Mjg0YTI2NTZlZWZmMDQ1ZTg2MzE5MWNcIikiLCJyZWZyZXNoVG9rZW5IYXNoMSI6IjQxYWVjZTNjN2FiOGQ1NzdkODc1MDg5MzgwY2Y5YjdmNDYyYTc3NDcxMGQ2NDlmOGNjYmZiYzJhZWNkMjY5MjMiLCJ1c2VyRGF0YSI6e30sImV4cGlyeVRpbWUiOjE2NTI5NzQ2NTE3NDUsInRpbWVDcmVhdGVkIjoxNjUyOTMxNDUxNzQ1LCJsbXJ0IjoxNjUyOTMxNDUxNzQ1fQ==.poq41KmXxE9ux4lgjIofwqpXI+N2aYakrKuf7/Y4WHMBStDfNURxQYHN58Kx84iCbLlGigz7ENpE4oLiLktPxnNeS2zSFxkpmW1QY2hnNDsOT4E7gNBL3YyOoSBVIsc+k9gIFkczCxqY2gjwzUTiQZvGfh1JSmP3EIYvF25uETPIYKlerWffNF4uKU5E77/OF3B+qEoobh6NYs4/TQQ3hKl475OAYMLva7jnw8qGeHwGSDPksO08M1feKH8mOURbANU1NQkI3jMk9AuyGtlbOgloACv9I38IlsGtzHwyoDE9eTSRBxrAoq/Ouy/7b37sIm0PC2tucssqWRwKzxGJMA==']
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:853 buffer(_:promise:) : request_part=metadata call_state=awaitingTransport (0 parts buffered) grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 buffering request part
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:200 send(_:promise:context:) : > Sending request with 'RobotSDK.App_BindMachineRequest: machineModel: "Rbot_air" '
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:853 buffer(_:promise:) : grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 call_state=awaitingTransport (1 parts buffered) request_part=message buffering request part
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:204 send(_:promise:context:) : > Closing request stream
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:853 buffer(_:promise:) : grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 call_state=awaitingTransport (2 parts buffered) request_part=end buffering request part
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] PlatformSupport.swift:199 makeClientBootstrap(group:logger:) : poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=324F3F12-7ED6-45FF-A2F4-4DC719148B9B/0 making client bootstrap with event loop group of type NIOTSEventLoop
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] PlatformSupport.swift:203 makeClientBootstrap(group:logger:) : poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=324F3F12-7ED6-45FF-A2F4-4DC719148B9B/0 Network.framework is available and the EventLoopGroup is compatible with NIOTS, creating a NIOTSConnectionBootstrap
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] ConnectionManager.swift:621 channelActive(channel:multiplexer:) : poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=324F3F12-7ED6-45FF-A2F4-4DC719148B9B/0 connectivity_state=connecting activating connection
11:28:02.424 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:499 receiveSettings(_:): HTTP2 settings update { grpc_connection_id=E8183975-D1EC-47B3-B6CA-9EC79B603D3F h2_settings_initial_window_size=8388608 h2_settings_max_concurrent_streams=0 h2_settings_max_frame_size=8388608 h2_settings_max_header_listsize=16384 } 2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:499 receiveSettings(:) : grpc.conn.addr_remote=::1 h2_settings_max_header_list_size=16384 h2_settings_max_concurrent_streams=100 h2_settings_max_frame_size=16384 grpc.conn.addr_local=::1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=324F3F12-7ED6-45FF-A2F4-4DC719148B9B/0 h2_settings_initial_window_size=8388608 HTTP2 settings update
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] ConnectionManager.swift:743 ready() : poolmanager.id=ObjectIdentifier(0x0000600003857e00) grpc_connection_id=324F3F12-7ED6-45FF-A2F4-4DC719148B9B/0 connectivity_state=active connection ready
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [🖤 TRACE] ConnectionPool.swift:661 tryServiceWaiters() : poolmanager.id=ObjectIdentifier(0x0000600003857e00) pool.waiters.count=1 servicing waiters
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [🖤 TRACE] ConnectionPool.swift:687 tryServiceWaiters() : poolmanager.id=ObjectIdentifier(0x0000600003857e00) pool.waiters.count=0 pool.waiters.serviced=1 done servicing waiters
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [💚 DEBUG] ClientTransport.swift:333 _transportActivated(channel:) : grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 activated stream channel
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:871 unbuffer() : grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 request_parts=3 grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 unbuffering request parts
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:881 unbuffer() : grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 request_part=metadata grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 unbuffering request part
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:509 write(context:data:promise:) : h2_headers=[([], ":method", "POST"), ([], ":path", "/app.Robot/BindMachine"), ([], ":authority", "localhost"), ([], ":scheme", "http"), ([], "content-type", "application/grpc"), ([], "te", "trailers"), ([], "grpc-timeout", "19999975u"), ([], "authorization", "Robot"), ([], "access_token", "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInZlcnNpb24iOiIyIn0=.eyJzZXNzaW9uSGFuZGxlIjoiMzk3YjZmNGYtNmYwZi00NGRjLWFhMzMtMjljMDcwMGI2MmEyIiwidXNlcklkIjoiT2JqZWN0SUQoXCI2Mjg0YTI2NTZlZWZmMDQ1ZTg2MzE5MWNcIikiLCJyZWZyZXNoVG9rZW5IYXNoMSI6IjQxYWVjZTNjN2FiOGQ1NzdkODc1MDg5MzgwY2Y5YjdmNDYyYTc3NDcxMGQ2NDlmOGNjYmZiYzJhZWNkMjY5MjMiLCJ1c2VyRGF0YSI6e30sImV4cGlyeVRpbWUiOjE2NTI5NzQ2NTE3NDUsInRpbWVDcmVhdGVkIjoxNjUyOTMxNDUxNzQ1LCJsbXJ0IjoxNjUyOTMxNDUxNzQ1fQ==.poq41KmXxE9ux4lgjIofwqpXI+N2aYakrKuf7/Y4WHMBStDfNURxQYHN58Kx84iCbLlGigz7ENpE4oLiLktPxnNeS2zSFxkpmW1QY2hnNDsOT4E7gNBL3YyOoSBVIsc+k9gIFkczCxqY2gjwzUTiQZvGfh1JSmP3EIYvF25uETPIYKlerWffNF4uKU5E77/OF3B+qEoobh6NYs4/TQQ3hKl475OAYMLva7jnw8qGeHwGSDPksO08M1feKH8mOURbANU1NQkI3jMk9AuyGtlbOgloACv9I38IlsGtzHwyoDE9eTSRBxrAoq/Ouy/7b37sIm0PC2tucssqWRwKzxGJMA=="), ([], "user-agent", "grpc-swift-nio/1.7.1-async-await.1")] h2_end_stream=false grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 h2_payload=HEADERS writing HTTP2 frame
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:881 unbuffer() : grpc.conn.addr_remote=::1 grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 request_part=message grpc.conn.addr_local=::1 unbuffering request part
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:536 write(context:data:promise:) : h2_payload=DATA grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 h2_data_bytes=14 h2_end_stream=false writing HTTP2 frame
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:881 unbuffer() : grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 grpc.conn.addr_remote=::1 request_part=end grpc.conn.addr_local=::1 unbuffering request part
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:569 write(context:data:promise:) : h2_payload=DATA grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 h2_data_bytes=0 h2_end_stream=true writing HTTP2 frame
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Channel] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:646 streamCreated(_:logger:) : grpc.conn.addr_remote=::1 poolmanager.id=ObjectIdentifier(0x0000600003857e00) h2_active_streams=1 h2_stream_id=HTTP2StreamID(1) grpc.conn.addr_local=::1 grpc_connection_id=324F3F12-7ED6-45FF-A2F4-4DC719148B9B/0 HTTP2 stream created
2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] ClientTransport.swift:900 unbuffer() : grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 grpc.conn.addr_local=::1 grpc.conn.addr_remote=::1 request buffer drained
11:28:02.434 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:646 streamCreated(_:logger:): HTTP2 stream created { grpc_connection_id=E8183975-D1EC-47B3-B6CA-9EC79B603D3F h2_active_streams=1 h2_stream_id=HTTP2StreamID(1) } 2022-05-25T11:28:02+0800 [RobotSDK.GRPC.Client] [🖤 TRACE] GRPCClientChannelHandler.swift:355 readHeaders(content:context:) : h2_headers=[([], ":status", "200"), ([], "content-type", "application/grpc")] h2_end_stream=false h2_payload=HEADERS grpc_request_id=2660F275-34BD-4365-B269-D78E1E95A001 received HTTP2 frame
2022-05-25T11:28:02+0800 [Robot] [💙 INFO] Interceptors.swift:226 receive(_:context:) : < Received headers: [':status': '200', 'content-type': 'application/grpc']
11:28:02.436 [server] [💚 DEBUG] GRPCIdleHandlerStateMachine.swift:668 streamClosed(_:logger:): HTTP2 stream closed { grpc_connection_id=E8183975-D1EC-47B3-B6CA-9EC79B603D3F h2_active_streams=0 h2_stream_id=HTTP2StreamID(1) } (lldb)