msmq multiple message types in a single queue - msmq

I'm planning on having a single queue receive ~100 different message types.
If I had only had 2 different types I'd do something like this
MessageQueue queue = new MessageQueue(_queue);
queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(CreateReportComand), typeof(CreateReportComand2)});
Is it craziness to pass XmlMessageFormatter an array of ~100 Types. And if not what is the best way to examine the received message to decide how to handle it?

You can use the WCF MsmqIntegrationBinding and handle messages of type MsmqMessage<string>. Then your handler method will receive the serialized message as a string and can do what you want with it after that.

I preffer not to use Message.Formatter and Message.Body. Instead I use Message.BodyStream manualy serializing/deserializing my messages.
Type of the message can be embeded in serialized data (that is what I do) or you can put it on message header or on label.

Related

How can I write to two OPC-UA array elements in order with Eclipse Milo?

I am running an OPC-UA server which I connect to with an Eclipse Milo client. There are two nodes that I want to be able to write to, both with the DataType Double Array[60].
In order to write over node values I have copied one of the client examples and integrated it into my code:
public void writeNodeValue(Node node, Object input) {
Variant v = new Variant(input);
DataValue dv = new DataValue(v, null, null);
NodeId nodeId = node.getNodeId();
CompletableFuture<StatusCode> f =
client.writeValue(nodeId, dv);
StatusCode statusCode = null;
try {
statusCode = f.get();
} catch (Throwable t) {
logger.error("Error writing value: {}", t.getMessage(), t);
future.completeExceptionally(t);
}
}
Firstly, is there an issue with this implementation, i.e. inputting an Object rather than a specific data type?
Additionally, I have two main questions regarding writing to an array node.
How can I write to a specific element of one of my arrays?
How can I guarantee that the client updates one array before the other?
Thanks for any advice you can provide.
Firstly, is there an issue with this implementation, i.e. inputting an Object rather than a specific data type?
It's fine to use Object in the type signature, but the value does actually have to be the type the server is expecting.
How can I write to a specific element of one of my arrays?
Using the indexRange parameter of WriteValue and calling the OpcUaClient::write method that accepts a List of WriteValue.
Or, if the server exposes each element as its own Node in the AddressSpace, you can try writing a scalar value directly to that Node.
In either case it's not a guarantee the server will support or allow it.
How can I guarantee that the client updates one array before the other?
Make two separate write calls and wait for the first to finish before you do the second.

Kafka Streams: Can someone point me to a fully implemented java example of sending messages to a DLQ (Dead Letter Queue) topic

I have an external dependency on another system in my streams app and would like to publish a message to DLQ kafka topic from within my streams app whenever a Deserialization/Producer/or any external/network exception happens, so that I can monitor that topic and reprocess records as needed. I can't seem to find a good example of doing this anywhere. The closest reference I found is https://docs.confluent.io/current/streams/faq.html#option-3-quarantine-corrupted-records-dead-letter-queue, but 1. It talks only about DeserializationExceptionHandler, what about other exception scenarios? 2. It doesn't demo the right way to configure/manage/close the associated KafkaProducer.
I would like to have try catch for the external dependency code and send the record(s) that cause exception to a dead letter queue topic. Any help will be appreciated!
For the processing logic you could take this approach:
someKStream
// the processing logic
.mapValues(inputValue -> {
// for each execution the below "return" could provide a different class than the previous run!
// e.g. "return isFailedProcessing ? failValue : successValue;"
// where failValue and successValue have no related classes
return someObject; // someObject class vary at runtime depending on your business
}) // here you'll have KStream<whateverKeyClass, Object> -> yes, Object for the value!
// you could have a different logic for choosing
// the target topic, below is just an example
.to((k, v, recordContext) -> v instanceof failValueClass ?
"dead-letter-topic" : "success-topic",
// you could completelly ignore the "Produced" part
// and rely on spring-boot properties only, e.g.
// spring.kafka.streams.properties.default.key.serde=yourKeySerde
// spring.kafka.streams.properties.default.value.serde=org.springframework.kafka.support.serializer.JsonSerde
Produced.with(yourKeySerde,
// JsonSerde could be an instance configured as you need
// (with type mappings or headers setting disabled, etc)
new JsonSerde<>()));
Your classes, though different and landing into different topics, will serialize as expected.
When not using to(), but instead one wants to continue with other processing, he could use branch() with splitting the logic based on the kafka-value class; the trick for branch() is to return KStream<keyClass, ?>[] in order to further allow one to cast to the appropriate class the individual items from KStream<keyClass, ?>[].

How to design the parameter if the type of parameter should be an abstract class

I'm design a chating App, and it's message has many type , for example : text, image, card, and the card message is very differect than the text message.
I don't want to create easy method to handle each message , because the message will be lose if the client doesn't support that message type(I want it to show "unsupported message type" instead of nothing happened)
What should I do on server side?
public async Task GroupMessage(string groupId, IMessage message) // the IMessage will lose many thing
{
}
The problem is that what's coming from the client isn't anything but some string data. SignalR has to bind that to the type in your handler. Therefore, all you're left with is IMessage, not something like Text or Image.
For this, you have no choice but to have different handlers, one for each type. That is the only way you can bind all the data, and then successfully interact with that data. You cannot use an abstract class or interface, unless you are fine with only having data that exists on that class or interface.

SyncVar without NetworkServer.Spawn

I have a somewhat complex tree of objects that is generated and configured at runtime. Since the information required to do this is available to both the server and the client, I would like to have both sides generate the objects independently and then link the networked parts up for syncing afterwards.
That is to say, I need a way to make SyncVar work for an object that exists on the server and client but was not originally spawned via NetworkServer.Spawn. Is there a way to manually configure NetworkIdentity such that the Unity networking system understands that something is the same object?
I have the ability to uniquely identify these objects across the network myself, I just need a way to communicate that to Unity. NetworkIdentity.netId is readonly, so that's not an option.
If you make all the initialisation done purely by the server and then pushed to the clients you remove the need to sync afterwards. This also would remove the need to deal with duplicate information (which would ultimately be wasted CPU time at client end).
However, if you are wanting to have clients create the data as well, then I would suggest you have them send appropriate messages to the server with their data, the server can then create the objects for them.
Setup message handlers with NetworkServer.RegisterHandler on the server instance for each type of message you need it to handle,
public enum netMessages{
hello = 101,
goodbye = 102,
action = 103,
}
...
NetworkServer.RegisterHandler((short)netMessages.hello, new NetworkMessageDelegate(hdl_hello));
NetworkServer.RegisterHandler((short)netMessages.goodbye, new NetworkMessageDelegate(hdl_goodbye));
...
private void hdl_hello (NetworkMessage msg){
nmgs_hello m = msg.ReadMessage<nmgs_hello>();
...
}
and use the Send method of NetworkClient to send messages to the server.
You will also need to define message classes based on MessageBase for the actual messages.
public class nmsg_hello : MessageBase {
public int x;
public float welcomeness;
}
NOTE: Make sure you don't base any of your network messages off each other, seems to be bug/feature in Unity (at least the last time I tried it) where it doesn't work if your message is derived from anything other than MessageBase as it's immediate ancestor.

Scala folding using Akka

I implemented in Java what I called a "foldable queue", i.e., a LinkedBlockingQueue used by an ExecutorService. The idea is that each task as a unique id that if is in the queue while another task is submitted via that same id, it is not added to the queue. The Java code looks like this:
public final class FoldablePricingQueue extends LinkedBlockingQueue<Runnable> {
#Override
public boolean offer(final Runnable runnable) {
if (contains(runnable)) {
return true; // rejected, but true not to throw an exception
} else {
return super.offer(runnable);
}
}
}
Threads have to be pre-started but this is a minor detail. I have an Abstract class that implements Runnable that takes a unique id... this is the one passed in
I would like to implement the same logic using Scala and Akka (Actors).
I would need to have access to the mailbox, and I think I would need to override the ! method and check the mailbox for the event.. has anyone done this before?
This is exactly how the Akka mailbox works. The Akka mailbox can only exist once in the task-queue.
Look at:
https://github.com/jboner/akka/blob/master/akka-actor/src/main/scala/akka/dispatch/Dispatcher.scala#L143
https://github.com/jboner/akka/blob/master/akka-actor/src/main/scala/akka/dispatch/Dispatcher.scala#L198
Very cheaply implemented using an atomic boolean, so no need to traverse the queue.
Also, by the way, your Queue in Java is broken since it doesn't override put, add or offer(E, long, TimeUnit).
Maybe you could do that with two actors. A facade one and a worker one. Clients send jobs to facade. Facade forwards then to worker, and remember them in its internal state, a Set queuedJobs. When it receives a job that is queued, it just discard it. Each time the worker starts processing a job (or completes it, whichever suits you), it sends a StartingOn(job) message to facade, which removes it from queuedJobs.
The proposed design doesn't make sense. The closest thing to a Runnable would be an Actor. Sure, you can keep them in a list, and not add them if they are already there. Such lists are kept by routing actors, which can be created from ready parts provided by Akka, or from a basic actor using the forward method.
You can't look into another actor's mailbox, and overriding ! makes no sense. What you do is you send all your messages to a routing actor, and that routing actor forwards them to a proper destination.
Naturally, since it receives these messages, it can do any logic at that point.