akka.net Tell (object) vs Tell (object, IActorRef) - c#

What is the difference? As I understood the Tell (object, IActorRef) sends original sender. But why not to use just the Forward method?
Thank you

You can think of actorRef.Tell(msg) as a shortcut for actorRef.Tell(msg, Context.Self), while actorRef.Forward(msg) keeps original message Sender. This also mean, that you need an active actor context in the background to have any meaningful Sender defined.
Using Tell(object, IActorRef) allows you to set Sender to any actor ref you like, including things like impersonation as another actor or ActorRefs.NoSender, which may be used i.e. to reduce size of a payload send over the wire, as the message sender won't be serialized.
In some of remote scenarios, if you don't expect to send an answer to a Sender, using actorRef.Tell(msg, ActorRefs.NoSender) may bring nice performance benefit.
Why? IActorRef is serialized as URI string (example: akka.tcp://system-name#localhost:9001/user/parent/child). When you're sending small messages i.e. stock price ticks or a game character position changes, this may mean that the most expensive part of your payload is actually a Sender.
Deserializing IActorRef also takes some extra time, because actor provider needs to resolve correct message transport for it.
For those reasons, if you don't need the Sender, using ActorRefs.NoSender may be a valid option.

Related

Will each QueueNotification of a push message lead to either a NotificationSent or NotificationFailed

I am new to Push messages and PushSharp.
I have a list of device ids to which I need to send a push notification message. But I do not want my program to wait on them forever. So I have two small questions:
Will each call to the QueueNotification method of a PushBroker object eventually lead to a NotificationSent or NotificationFailed event?
Can I use the Tag property of GcmNotification and AppleNotification objects to store the device id so I will know who the received exactly was?
In my app I've always seen a Sent event raised, but this might not always be the case.
Yes you can use the tag property to store an identifier for the message, which can be retrieved on the sent/failed events.
I think this link has more detail which might be helpful.
Regards,

Identifying a property name with a low footprint

I wish to send packets to sync properties of constantly changing game objects in a game. I've sent notifications of when a property changes on the server side to a EntitySync object that is in charge of sending out updates for the client to consume.
Right now, I'm pre-fixing the property string name. This is a lot of overhead for when you're sending a lot of updates (position, HP, angle). I'd like for a semi-unique way to idneity these packets.
I thought about attributes (reflection... slow?), using a suffix on the end and sending that as an ID (Position_A, HP_A) but I'm at a loss of a clean way to identify these properties quickly with a low foot print. It should consume as few bytes as possible.
Ideas?
Expanding on Charlie's explanation,
The protobuf-net library made by Marc Gravell is exactly what you are looking for in terms of serialization. To clarify, this is Marc Gravell's library, not Googles. It uses Google's protocol buffer encoding. It is one of the smallest footprint serializes out there, in fact it will likely generate smaller packets than you manually serializing it will ( How default Unity3D handles networking, yuck ).
As for speed, Marc uses some very clever trickery (Namely HyperDescriptors) http://www.codeproject.com/Articles/18450/HyperDescriptor-Accelerated-dynamic-property-acces
to all but remove the overhead of run time reflection.
Food for thought on the network abstraction; take a look at Rx http://msdn.microsoft.com/en-us/data/gg577609.aspx Event streams are the most elegant way I have dealt with networking and multithreaded intra-subsystem communication to date:
// Sending an object:
m_eventStream.Push(objectInstance);
// 'handling' an object when it arrives:
m_eventStream.Of(typeof(MyClass))
.Subscribe ( obj =>
{
MyClass thisInstance = (MyClass) obj;
// Code here will be run when a packet arrives and is deserialized
});
It sounds like you're trying to serialize your objects for sending over a network. I agree it's not efficient to send the full property name over the wire; this consumes way more bytes than you need.
Why not use a really fantastic library that Google invented just for this purpose.
This is the .NET port: http://code.google.com/p/protobuf-net/
In a nutshell, you define the messages you want to send such that each property has a unique id to make sending the properties more efficient:
SomeProperty = 12345
Then it just sends the id of the property and its value. It also optimizes the way it sends the values, so it might use only 1, 2, 3 bytes etc depending on how large the value is. Very clever, really.

ChannelFactory.Open VS IClientChannel.Open

I am trying to get a better understanding of some of the inner workings of WCF. I have done a fair amount of looking around, but I have not been able to find a clear explanation of what ChannelFactory.Open() does compared to IClientChannel.Open(). What is the purpose of opening the factory? If the channel is being used for communication, what part does the factory play in the process after the channel has been created and opened?
The question was asked here, among other questions, but never answered directly.
EDIT:
After de-compiling the source code, I found some of the specific reasons why Open needs to be called on ChannelFactory, which is documented below.
What I'm still having trouble understanding is why this work is being done through mechanisms provided by the ICommunicationObject, when the factory isn't actually communicating with anything (as far as I know). Why not just handle these things when the object is constructed or disposed of?
I think I'm probably far enough in the weeds that such an answer may not be publicly available. Thank you to those who weighed in on the original question.
Open needs to be called in the factory, since it's an ICommunicationObject - before you use one of those, it needs to be opened. But in most cases the factory is opened automatically for you when you call things such as CreateChannel, for example, so you seldom need to worry about explicitly opening the factory.
Regarding Close, it really depends on which binding the factory is using. In most cases you're correct, the resource is mostly associated with the channel. But it's possible that a certain binding would multiplex multiple channels in the same underlying connection, so closing the channel would simply remove the channel from the list to be multiplexed. Only when the factory is closed is that the underlying connection is actually released.
After de-compiling a bunch of the related classes in System.ServiceModel, I was able to get a little more information.
The Open call appears to make its way down the inheritance tree to the CommunicationObject, where its Open method is called. All this seems to do is provide a bunch of diagnostic information and raise a number of events.
The ChannelFactory class uses the Open events do a number of things, including creating its inner channel factory:
protected override void OnOpening()
{
base.OnOpening();
this.innerFactory = this.CreateFactory();
if (this.innerFactory == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("InnerChannelFactoryWasNotSet")));
}
}
As has been mentioned by others here, the Close events are also used to do things like close all of the underlying channels, (by way of it's internal channel factory):
protected override void OnClose(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
while (true)
{
IChannel channel;
lock (base.ThisLock)
{
if (this.channelsList.Count == 0)
{
break;
}
channel = this.channelsList[0];
}
channel.Close(timeoutHelper.RemainingTime());
}
}
Opening ChannelFactory or the innerchannel just change the state of the object, when is instantiated is starts in the Created state, the object can be configured but it is not usable to send or receive message, in the Opened state, the communicationObject is usable but it is no longer configurable
So the purpose of opening the factory is just a design choice and it is indeed done automatically when you create the first channel, it does not to much under the hood, the factory is responsible to create the channel that will actually bring messages from the transport layer and send them to you application.
Channel factories are responsible for creating channels. Channels
created by channel factories are used for sending messages. These
channels are responsible for getting the message from the layer above,
performing whatever processing is necessary, then sending the message
to the layer below. The following graphic illustrates this process
http://msdn.microsoft.com/en-us/library/ms789050.aspx
Hope this helps

Custom message framing protocols for TCP server/client

I use Net.Sockets.Socket class to write a TCP server. Since TCP operates on streams, one needs an approach to seperate messages from each other. (For details, see the Message Framing post of Stephen Cleary in his blog here.)
What I want to achieve is writing a TCP server class with the support for custom message framing protocols. An example initialization of this class is here:
var receiveDelimiter = Encoding.UTF8.GetBytes("[END]");
var sendDelimiter = Encoding.UTF8.GetBytes("\r\n");
var protocol = new DelimiterFramingProtocol(receiveDelimiter, sendDelimiter);
var server = new Server(protocol);
server.Start(port);
The protocol should be derived from the abstract class MessageFramingProtocol and the server should be able to use it to seperate messages. In the example above, the server should only fire its DataReceived event if the delimiter (which is "[END]") is received and the arguments of DataReceived should only have the part of the message that is before the delimiter. If there are more bytes received after the delimiter, the server should store them and fire DataReceived only when the delimiter is received again. Server also should send the sendDelimiter after every message that it sends.
What I need is not this whole server class or any of the protocol classes. What I need is a template, a design advice. Assuming I have a property of type FramingProtocol called Protocol in the server class, how can I use it in receiving and sending operations in the Server class? What abstract methods / properties it should have to provide the flexibility that you see above? I should be able to write custom protocol classes that derive from FramingProtocol. They may use delimiters, length-prefixing, both of them or other, custom approaches to seperate messages.
I wouldn't go with only one Protocol instance that is passed to the server - it will need lots of them. Provide the server with a factory class that either creates new Protocol instances or depools them from a pool created and filled at startup.
What I usually do is something like this:
RX:
Provide an 'int Protocol::addBytes(char *data,int len)' function. Fed with the address and length of raw rx data, the function returns either -1, (means that it has consumed all the raw data without fully assembling a protocol unit), or a positive integer that is the index of data consumed at the point it assembled a valid PDU. If the instance manages to assemble a PDU, it can be further processed, (eg. fired into a 'DataReceived(Protocol *thisPDU)' event and a new Protocol instance created, (or depooled), and loaded up with the remaining raw data.
TX:
Provide, (quite possibly overloaded), 'bool Protocol::loadFrom(SomeDataClass * outData, OutStreamClass *outStream)' methods that can load data from whatever source into internal member vars so that a complete set of data exists to generate a serialized PDU, (and return false, or raise an exception if there is some issue - eg. provided data fails sanity-check). If no error is detected, the instance drives the serialized data out of the passed 'outStream' stream/socket/buffer+len.

TPL Dataflow message type allocation pattern possible?

I run an algorithm that receives out-of-process messages of different types. The incoming messages are actually byte arrays and each byte array is pre-pend by a byte array flag indicating the message type. I like to understand whether it is possible to setup an IPropagator<byte[], byte[]> that processes the incoming byte arrays, interprets the byte array flags and then streams the byte array to a specific corresponding linked ActionBlock.
For example lets say I have 2 different message types and I have 2 different corresponding ActionBlocks that should only receive messages that match with the intended message type they are supposed to receive. I believe if I just link the IPropagatorBlock to both Actionblocks that both ActionBlocks will receive the same message? How can I correctly allocate each message depending on its flag (do not worry about the flag, the identification is trivial, lets assume I know at any time to which ActionBlock IPropgatorBlock wants to stream the message)? I am struggling with correctly setting up the data flow structure. I would love to be able to link the data blocks directly to each other rather than having to Post(). Is that possible?
Any help in that regards is much appreciated.
This depends on the IPropagatorBlock that you're using. If it's a custom one, you can do anything, including for example recognizing which target block to use based on the order they're linked (or something more reliable).
But assuming the block is actually a normal TransformBlock (or something like that), I think the best option is to use the overload of LinkTo() that takes a predicate, and adding the flag to the output type (which means changing the type of the block to IPropagatorBlock<byte[], Tuple<FlagType, byte[]>>, or a custom type instead of the Tuple). If you do this, then you can be sure that the target will receive the message only if the predicate for that target matches the message.
Also, what happens if you link one source block to more target blocks depends on the source block. In most cases, it sends each message to exactly one target: it first tries the first target, and only tries the second one if the first one declines or postpones the message. The exception to this rule is BroadcastBlock (and the similar WriteOnceBlock), that always tries to send each message to all targets. Again, a custom block can behave any way it wants.

Categories

Resources