Can 'BrokerNotAvailableException' happen during producing a Kafka message? - apache-kafka

I see 'BrokerNotAvailableException' from the below list http://kafka.apache.org/20/javadoc/org/apache/kafka/common/errors/BrokerNotAvailableException.html
but I don't see this in the exceptions for a Callback.
https://kafka.apache.org/25/javadoc/org/apache/kafka/clients/producer/Callback.html
Does it mean, BrokerNotAvailableException will not happen when using Callback?

Related

reactive 4.2.0 net Subject<T> ReplaySubject<T>

I am using ReplaySubject as a pipe when I feed the Observer with OnNext messages and then I subscribe to the message in another part of the code.
I tried ISubject first, by using Subject.Create(observer:, observable:) but this seems to do nothing, or in other words, the Observer is a sink that goes nowhere. Is there some code that will make the Subject do something pipe-like. For example, I want to inject onNext messages with a integral countN and I want the observable to broadcast N-many 0.00E0(s) in sequence.
UPDATE:
It seems I need to implement the ISubject interface. Is there source code for a simple implementation that functions the same as ReplaySubject, with simple, proper memory handling of buffer size and Observer collection and Disposable return object.
Ok, so you use
new Subject<Int32>()
to get a subject that is a pipe-line.
Someone care to explain what Subject.Create does?
Can you inherit from Subject or ReplaySubject? Should you be able to?

How to ignore special error in RxJava

I would like to ignore error if it is an instance of for example SpecialError() and not to break the chain.
You can use retry(Predicate<Throwable>) to restart the stream for specific throwables, otherwise it will continue the onError up the chain.
It is impossible to continue a stream after onError has been called however, since the specification defines it as a terminal event.

How to request a replay of an already received fix message

I have an application that could potentitally throw an error on receiving a ExecutionReport (35=8) message.
This error is thrown at the application level and not at the fix engine level.
The fix engine records the message as seen and therefore will not send a ResendRequest (35=2). However the application has not processed it and I would like to manually trigger a re-processing of the missed ExecutionReport.
Forcing a ResendRequest (35=2) does not work as it requires modifying the expected next sequence number.
I was wonderin if FIX supports replaying of messages but without requiring a sequence number reset?
When processing an execution report, you should not throw any exceptions and expect FIX library to handle it. You either process the report or you have a system failure (i.e. call abort()). Therefore, if your code that handles execution report throws an exception and you know how to handle it, then catch it in that very same function, eliminate the cause of the problem and try processing again. For example (pseudo-code):
// This function is called by FIX library. No exceptions must be thrown because
// FIX library has no idea what to do with them.
void on_exec_report(const fix::msg &msg)
{
for (;;) {
try {
// Handle the execution report however you want.
handle_exec_report(msg);
} catch(const try_again_exception &) {
// Oh, some resource was temporarily unavailable? Try again!
continue;
} catch(const std::exception &) {
// This should never happen, but it did. Call 911.
abort();
}
}
}
Of course, it is possible to make FIX library do a re-transmission request and pass you that message again if exception was thrown. However, it does not make any sense at all because what is the point of asking the sender (over the network, using TCP/IP) to re-send a message that you already have (up your stack :)) and just need to process. Even if it did, what's the guarantee it won't happen again? Re-transmission in this case is not only doesn't sound right logically, the other side (i.e. exchange) may call you up and ask to stop doing this crap because you put too much load on their server with unnecessary re-transmit (because IRL TCP/IP does not lose messages and FIX sequence sync process happens only when connecting, unless of course some non-reliable transport is used, which is theoretically possible but doesn't happen in practice).
When aborting, however, it is FIX library`s responsibility not to increment RX sequence unless it knows for sure that user has processed the message. So that next time application starts, it actually performs synchronization and receives missing messages. If QuickFIX is not doing it, then you need to either fix this, take care of this manually (i.e. go screw with the file where it stores RX/TX sequence numbers), or use some other library that handles this correctly.
This is the wrong thing to do.
A ResendRequest tells the other side that there was some transmission error. In your case, there wasn't, so you shouldn't do that. You're misusing the protocol to cover your app's mistakes. This is wrong. (Also, as Vlad Lazarenko points out in his answer, if they did resend it, what's to say you won't have the error again?)
If an error occurs in your message handler, then that's your problem, and you need to find it and fix it, or alternately you need to catch your own exception and handle it accordingly.
(Based on past questions, I bet you are storing ExecutionReports to a DB store or something, and you want to use Resends to compensate for DB storage exceptions. Bad idea. You need to come up with your own redundancy solution.)

How to respond immediately to a SOAP message in Camel, while invoking other processing?

Basically, I'm looking to respond to a SOAP request immediately, but also kick off further processing. What I'm seeing is that the response is not sent until the route ends. In other words:
from("cxf:bean:someEndpoint")
.to("seda:replySOAP")
.to("direct:ABCMessage");
from("seda:replySOAP")
.to("bean:soapReply?method=process").end();
from("direct:ABCMessage")
.process(new ConvertABCToNZFCY())
.to("bean:prelimNZFCYCall")
.end();
Does not generate the response until "direct:ABCMessage" has completed. I would think seda would designate asynchronous processing. I have also tried "vm:replySOAP", pointing to a separate Camel Context, and this did not help.
I have also tried multicast, to no avail:
from("cxf:bean:someEndpoint")
.multicast().parallelProcessing()
.to("seda:replySOAP")
.to("direct:ABCMessage");
What DOES work for me is wireTap, but it does not seem elegant:
from("cxf:bean:someEndpoint")
.wireTap("direct:ABCMessage")
.to("direct:replySOAP");
Must I use JMS?
Thanks!
The behavior you see is due to
.to("direct:ABCMessage");
in the routes. It is a synchronous process ie, an InOut exchange pattern. jms can be used but that may be an overkill if you are using it only to avoid wiretap. Why do you think wiretap does not seem elegant.

Remove read topic from DDS

I have a problem with subscribing the data (using the java platform). When a subscriber subscribes to a topic, that subscribed data must be removed from the DDS. But in my case whenever I subscribe to the data the same data is subscribed many times. The data is not removed from the DDS. I tried with QoS but I don't know how to use it.
Please suggest how I can remove the read data from the DDS.
This behavior is not caused by your QoS settings, but by your method of accessing the DataReader. When you retrieve your data, you are probably calling something like the following read() in a loop:
FooReader.read(
dataSeq, infoSeq, 10,
ANY_SAMPLE_STATE.value,
ANY_VIEW_STATE.value,
ANY_INSTANCE_STATE.value);
The read() method invoked like this will return all currently available samples in your FooReader. After the read(), those samples still remain available in the FooReader, that is how the read() method behaves. Think of a read as a "peek". The next time that you invoke the read() method in this way, you will see all samples that you saw before, unless they have been overwritten by a new update from a DataWriter.
To resolve your issue, you could replace the read() with a take(), like this:
FooReader.take(
dataSeq, infoSeq, 10,
ANY_SAMPLE_STATE.value,
ANY_VIEW_STATE.value,
ANY_INSTANCE_STATE.value);
The take() method is different from the read() method in that it does a destructive read; it not only reads the data but also removes it from FooReader. That way, you will never receive the same sample twice. In fact, if you consistently use take() as opposed to read(), you will never be able to see any sample twice.
Another way to resolve your issue is to stick with read(), but adjust the requested SAMPLE_STATE, from ANY to NOT_READ, like this:
FooReader.read(
dataSeq, infoSeq, 10,
NOT_READ_SAMPLE_STATE.value,
ANY_VIEW_STATE.value,
ANY_INSTANCE_STATE.value);
That way, you will only read samples that you have not read previously. The difference with take() in this case is that the data does remain available in your FooReader, which might be useful if you want to re-read it at a later stage (in which case you need to use the ANY sample state as opposed to NOT_READ to obtain previously read samples).