A solution has been found.
```
while ( true ) {
grpc_core_FilterStackCall *filterStackCall = (grpc_core_FilterStackCall 
*)calld ->call_;
grpc_completion_queue *call_cq_pluck = filterStackCall ->cq_;
int num_polls = call_cq_pluck ->num_polls; // no thread safe
if ( num_polls > 0 ) {
cqd_pluck ->shutdown = true; // atomic
break;
}
std::this_thread::sleep_for( std::chrono::milliseconds( 300 ) );
}
```
It is better, of course, to use `grpc::internal::BlockingUnaryCall`, which 
can accept `google::protobuf::Message*`
created via `google::protobuf::DynamicMessageFactory`
The channel `server ->InProcessChannel( grpc::ChannelArguments{ } );` is 
suitable for both reflection and calling.
On Tuesday, November 14, 2023 at 9:10:53 PM UTC+3 Alexovsky wrote:

> Hello, I’m exploring the possibility of calling service methods and 
> passing existing data to it.
> That is, starting the server to function without an explicit connection to 
> the client and receiving data from the client. This is something like a 
> transport, should work over UDP and is suitable for *unary* requests and 
> responses.
> Based on *helloworld*.
> Used: hack of contract violation and access to private fields; custom 
> types for mirroring inaccessible types from *.cc.
> Everything works, `GreeterServiceImpl::SayHello` is called with the 
> necessary data, and there are the following problems.
> I’m struggling with resource leaks now and the thread 
> `ThreadInternalsWindows::thread_body` hangs forever in the function
> `grpc::internal::UnaryRunHandlerHelper()` on call
> `param.call->cq()->Pluck(&ops);`
> Any ideas on how to fix it? Or perhaps try a different approach to calling 
> service methods?
> Here are some of the steps:
> ```
> // client data, from gRPC helloworld, done as SerializeToArray()
> std::vector< unsigned char > fromUdp = { 0x0a, 0x05, 0x77, 0x6f, 0x72, 
> 0x6c, 0x64 };
> // get grpc_core server
> ::grpc_core::Server *servC = ::grpc_core::Server::FromC( server 
> ->c_server( ) );
> // 'unprivate' hack to get access to 
> '&grpc_core::Server::registered_methods_'
> typedef std::vector<std::unique_ptr<grpc_core::Server::RegisteredMethod>> 
> &rm_t;
> rm_t vecRm2 = (servC) ->*get(B_member());
> // at index 0 is "/helloworld.Greeter/SayHello"
> grpc_core_Server_RegisteredMethod *srm0 = 
> (grpc_core_Server_RegisteredMethod *)vecRm2[ 0 ].get( );
> // main method
> auto matcher = srm0 ->matcher.get( );
> // main call object
> grpc_call_create_args args_call_create = {};
> // emulate grpc_core::Server::ChannelData::AcceptStream and 
> Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone
> ...
> // create channel 
> ...
> absl::StatusOr<grpc_core::RefCountedPtr<grpc_core::Channel>> channel0 = 
> grpc_core::Channel::CreateWithBuilder( &builder );
> grpc_core::RefCountedPtr<grpc_core::Channel> channelX = channel0.value( );
> ...
> // filling main call object
> args_call_create.channel = channelX;
> args_call_create.server = servC;
> args_call_create.server_transport_data = reinterpret_cast<void* >( id ); 
> // for !is_client
> args_call_create.send_deadline = grpc_core::Timestamp::InfFuture( );
> // prepare to filling client data
> grpc_call* call;
> grpc_error_handle error = grpc_call_create( &args_call_create, &call );
> grpc_call_stack* call_stack = grpc_call_get_call_stack( call );
> grpc_call_element* elem = grpc_call_stack_element(call_stack, 0);
> auto* calld = static_cast<grpc_core::Server::CallData*>(elem->call_data);
> calld ->Start( elem );
> // filling client data
> calld ->payload_ = grpc_raw_byte_buffer_create( nullptr, 0 );
> grpc_byte_buffer* buffer = calld ->payload_;
> grpc_core::SliceBuffer buf;
> grpc_core::Slice single = grpc_core::Slice::FromCopiedBuffer( 
> fromUdp.data( ), fromUdp.size( ) );
> buf.Append( std::move( single ) );
> grpc_slice_buffer_move_into( buf.c_slice_buffer( ), &calld ->payload_ 
> ->data.raw.slice_buffer );
> // call main method
> matcher ->MatchOrQueue( 0, calld );
> // something to wait execution in other thread
> std::this_thread::sleep_for( std::chrono::seconds( 3 ) );
> ```
> I think I need to emulate a call to some kind of `grpc_closure` in 
> `ExecCtx::Flush`, I can’t find it yet.
> This is my first post. While searching, I couldn't find anyone posting 
> links to their repo here. Can I post a GitHub link here as an add-on?
>

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/c4a57e9d-0999-484f-82df-5208338b2eedn%40googlegroups.com.

Reply via email to