I am trying to call a camel route xml from the Java method. Is it possible to call and return to the same method again?
Yes, you can use a ProducerTemplate for that.
If your caller has to wait for the route to complete, your route must be executed synchronously (for example direct routes). See exchange pattern for more details.
If you expect a response from the route you should use one of the request* methods of the producer template (not the send* methods).
Related
I would like to make client-side streaming blocking. The definition of that protocol can look like this:
rpc RecordRoute(stream Point) returns (RouteSummary) {}
As it's said in the documentation, for certain types of streaming call, it's only possible to use async stub:
a non-blocking/asynchronous stub that makes non-blocking calls to the server, where the response is returned asynchronously. You can make certain types of streaming call only using the asynchronous stub.
Then how can I make that call blocking/synchronous? Is it possible?
Blocking stub can only be used for RPCs that client sends only a single request. For client streaming calls, you can only use async stub. The generated code for blocking stub does not contain the RPC method for client-streaming or bidi-streaming methods.
If you want to avoid excessive buffering due to async requests, you can use the CallStreamObServer API to do manual flow control. With some external synchronizations such as a CountDownLatch, the async API can behave synchronously. See how gRPC's manual flow control example works.
I've implemented the producer/consumer paradigm with a message broker in Spring and my producers use WebSocket to extract and publish data into the queue.
A producer is therefore something like:
AcmeProducer.java
handler/AcmeWebSocketHandler.java
and the handler has been a pain to deal with.
Firstly, the handler has two events:
onOpen()
onMessage()
onOpen has to send message to the web socket to subscribe to specific channels
onMessage receives messages from WebSocket and adds them into the queue
onMessage has some dependencies from AcmeProducer.java, such as it needs to know currency pairs to subscribe to, it needs the message broker service, and an ObjectMapper (json deserializer) and a benchmark service.
When messages are consumed from the queue they are transformed into a format for OrderBook.java. Every producer has its own format of OrderBook and therefore its own AcmeOrderBook.java.
I feel the flow is difficult to follow, even though I've put classes for one producer in the same package. Every time I want to fix something in a producer I have to change between classes and search where it is.
Are there some techniques for reducing the complicated data flow into something easy to follow?
As you know, event handlers like AcmeHandler.java hold callbacks that get called from elsewhere in the system (from the websocket implementation) and hence they can be tricky to organize. The data flow with events is also more convoluted because when handlers are in separate files they cannot use variables defined in the main file.
If this code would not use the event driven paradigm the data flow would be easy to follow.
Finally, is there any best practice for structuring code when using web sockets with onOpen and onMessage? Producer/Consumer is the best I could come up with, but I don't want to scatter classes of Acme in different packages. For example, the AcmeOrderbook should be in a consumer class, but as it depends on the AcmeProducer.java and AcmeHandler.java they are often edited at the same time, hence I've put them together.
As the dependencies inside every WebSocket handler are the same (only different implementations of those same interfaces) I think there should be only one thing injected, and that will be some Context variable. Is that the best practice?
I've solved it using Message Dispatcher and Message Handlers.
The dispatcher only checks if the message is a data message (snapshot or update) and passes control to the message handler class which itself checks the type of the message (either snapshot or update) and handles that type properly. If the message is not a data message but something else the dispatcher will dispatch the message depending on what it is (some event).
I've also added callbacks using anonymous functions and they are much shorter now, the callbacks are finally transparent.
For example, inside an anonymous callback function there is only this:
messageDispatcher.dispatchMessage(context);
Another key approach here is the use of context.MessageDispatcher is a separate class (autowired).
I've separated orderbook into its directory inside every producer.
Well, everything requires knowledge of everything to solve this elegantly.
Last pattern for solving this: Java EE uses annotations for their endpoints and control functions such as onOpen, onMessage, etc. That is also a nice approach because with it the callback becomes invisible and onOpen / onMessage are automatically called by the container (using the annotation).
I am a java beginner, I met a problem in my Restful class, I just wonder when my code is working on the Restful Class, like the thread is still working on one url request, at the same time I send another request to invoke the same Restful Class, this can work properly or not?
Now, I set a client using "GET" method. Do I need to change the method "GET" so the thread does not need to wait to the "Response"?
Any help, thanks a lot~
When you are using a framework, things are very easy. To answer your questions
How does the class behave when two simultaneous requests are made?
Each of your request will run in a separate thread. So its as simple as two different threads accessing a method simultaneously. Care must be taken not to use any shared resources (including instance variables) in the method. In that case, this becomes a bit tricky.
Do I need to change the method "GET" so the thread does not need to wait to the "Response"?
I am not sure what you mean by this. When you use HTTP, a request will always be accompanied by a response. That's how the the protocol works. Even in case of an asynchronous scenario, an immediate notional response is always returned.
I would like to implement a distinct thread for each route in apache camel.I do not want to use a thread pool or async as I want my process to remain synchronous.Could I please get a code example for the same in java DSL format.
Each route uses its own thread, unless a route is using the direct component (http://camel.apache.org/direct), which will re-use the caller thread.
For example having 2 routes
from("file:foo").to("bean:blah");
from("jms:queue:bar").to("bean:great")
Is 2 routes, and each route uses its own thread.
On the other hand the following 2 routes
from("file:foo").to("bean:blah").to("direct:bar");
from("direct:bar").to("bean:great")
Then the 2nd route being a direct endpoint, will re-use the caller thread, from the 1st route, when the 1st route routes the message to it, using: .to("direct:bar")
you can use camel-direct to have to a single-threaded, synchronous request/response route...
I have developed the following program/architecture:
A) A Java servlet receives POST requests, gets the Parameters from the POST requests and stores them in a public static LinkedList:
public static LinkedList incomingQueue = new LinkedList<myObjects>();
That is, for every POST request I do this:
incomingQueue.push(myObject);
Now, I want to periodically access the Queue and perform processing on the Objects:
while(true){
doProcessing(incomingQueue);
wait(someTime);
}
Obviously, I don't have a main class to do this. How do I create such a class that has access to the incomingQueue without being triggered by the servlet? What is the correct architecture to do this?
Thank you for your time.
First of all the queue should be placed in servlet context attributes (see: ServletContext.setAttribute(). Also access to this queue must be synchronized, consider ArrayBlockingQueue.
In plain servlets you can use ServletContextListener by starting a thread in contextInitialized() and interrupting it in contextDestroyed.
If you are using spring you can use #Scheduled annotation, in ejb: TimerService or #Schedule.
Finally there is a Timer class in standard Java. Last but not least, have a look at jms, it might be a better choice in your situation.
You have several options:
Use a scheduling library like Quartz
If you don't want to use a separate library, you should add a Listener to your web.xml that extends ServletContextListener and starts a separate thread on contextInitialized().
Also: Note the comment by #BrianRoach. The point about the synced list is rather important.
You need to synchronize your methods for concurrent access.
A very hard core solution would be to implement it like producer and consumer. Here is an example that uses stack and 1 producer and 3 consumers.
Much neater solution would be to use JMS.