Comments (16)
This won't compile as well
agrpc::repeatedly_request(m_service,
asio::bind_executor(
m_grpc_context.get_executor(),
[p = this](agrpc::GenericRepeatedlyRequestContext<>&& ctx) mutable
{
asio::spawn(p->m_grpc_context, [](auto) { });
})
);
from asio-grpc.
By capturing GenericRepeatedlyRequestContext
in the lambda, the lambda becomes move-only (because GenericRepeatedlyRequestContext
is move-only). You then pass it as lvalue-reference to asio::spawn
which then tries to make a copy of it. I don't compile with -fpermissive
so I get a different error:
[build] boost/asio/impl/spawn.hpp(1013): error C2280: 'GenericRequestHandler::()::<lambda_1>::<lambda_1>(const GenericRequestHandler::()::<lambda_1> &)': attempting to reference a deleted function
Solution is to move the lambda:
auto f = [ctx = std::move(ctx)](asio::yield_context yield) // btw yield_context is essentially just a shared_ptr, you should consider taking it by const&
{
};
asio::spawn(m_grpc_context, std::move(f)); // std::move added here
In more recent versions of asio you also need to provide a completion token to asio:;spawn
, example:
asio::spawn(m_grpc_context, std::move(f), asio::detached);
Your example with repeatedly_request compiles fine for me but looks incomplete? Of course I assume that m_service
is of type grpc::AsyncGenericService
.
from asio-grpc.
There must be something else, this code also won't compile
agrpc::repeatedly_request(m_service,
asio::bind_executor(
m_grpc_context.get_executor(),
[this](agrpc::GenericRepeatedlyRequestContext<>&& ctx)
{
auto f = [](auto) { };
asio::spawn(m_grpc_context, std::move(f));
})
);
from asio-grpc.
Ok, can you show the surrounding member function and the declaration of the member variables m_service
and m_grpc_context
?
from asio-grpc.
agrpc::GrpcContext m_grpc_context;
grpc::AsyncGenericService m_service;
The member function on the other hand
void run()
{
agrpc::repeatedly_request(m_service,
asio::bind_executor(
m_grpc_context.get_executor(),
[this](agrpc::GenericRepeatedlyRequestContext<>&& ctx)
{
...
});
})
);
}
from asio-grpc.
Thank you. You should remove the const
from this function:
auto get_executor() const noexcept { return m_grpc_context.get_executor(); }
from asio-grpc.
I did try this to remove, both from this function and from the operator()(...)
but it did not help. I am rewriting the logic with stackless coroutines to I don't have to call spawn
.
from asio-grpc.
But how would your code work without const?
from asio-grpc.
Can you give me more context, for example more of the surrounding code? Also what version of asio are you using?
from asio-grpc.
Also more of the error message, I don't think it is just one line?
from asio-grpc.
Try this one:
asio::spawn(m_grpc_context.get_executor(), std::move(f));
Looks like older versions of asio have issues identifying GrpcContext
as an asio::execution_context
.
EDIT: Nevermind, not actually the case
from asio-grpc.
I ended up implementing with stackless coroutines. It less convenient but can make my code more general with async_compose
. Don't have much time now to investigate what was the problem. BTW why some completions have signature
void (boo)
instead of void (error_code)
I will have to write my own error codes?
from asio-grpc.
The void(bool)
comes directly from gRPC. The grpc::CompletionQueue only provides a simple bool when an operation completes. The meaning of the bool depends on the function, for example, for agrpc::read
:
true
indicates that a valid message was read.false
when there will be no more incoming messages, either because the other side has called WritesDone() or the stream has failed (or been cancelled).
from asio-grpc.
Ok. But what about functions like write_and_finish
that I suppose perform two grpc function calls? Without an error code I can't possibly know which of the two operations had an error?
from asio-grpc.
write_and_finish
is actually just one gRPC call provide by the gRPC library (see here). The meaning of the returned bool
is explained in the official documentation and copied into asio-grpc documentation:
true
means that the data/metadata/status/etc is going to go to the wire. If it isfalse
, it is not going to the wire because the call is already dead (i.e., canceled, deadline expired, other side dropped the channel, etc).
On the server-side, gRPC does not provide detailed information on why a message couldn't be send to the client. They just give these possible reasons:
This could be because of explicit API cancellation from the client-side or server-side, because of deadline exceeded, network connection reset, HTTP/2 parameter configuration (e.g., max message size, max connection age), etc.
from asio-grpc.
Great, thanks.
from asio-grpc.
Related Issues (20)
- Provide operator bool to check the validity of ServerPRCPtr HOT 1
- Question: add sender after run HOT 1
- simple program stuck HOT 2
- Consult some questions HOT 9
- Asio-gRPC seems to have TSAN warnings HOT 8
- How to detect client closed connection HOT 6
- Can I call ServerBuilder::BuildAndStart() after GrpcContext::run() HOT 2
- Questions on how to switch from an GrpcContext to io_context and back HOT 6
- How to shutdown grpc clients HOT 1
- Clarification Needed on Thread Context Switch in writer() Function (example streaming-server.cpp) HOT 8
- assertion failed: !started_ HOT 2
- Can I use asio-grpc inside an existing boost::asio application? HOT 7
- The agrpc::GrpcContext hangs forever HOT 13
- an upgrade from 2.5.1 to 2.9.1 leads to build errors HOT 6
- build fails with latest boost 1.84 HOT 4
- [Question]: Slowly receiveing client in long-lived streaming HOT 6
- InvokeHandler conflicts with Objective-C/C++ defines HOT 1
- Need some basic help! HOT 9
- How to make grPC Client to Establish connection based on IP address? HOT 2
- Update conan package to 3.0.0 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from asio-grpc.