I wish to be able to post messages from the main application of a DataSnap automation server to the RemoteDataModule instances created to service clients.
I understand from other forum entires, such as:
Delphi Multi-Threading Message Loop
That messages can be handled in threads without the need to create a Windows handle for the purpose; messages posted with PostThreadMessage.
However the DataSnap TComponentFactory creates a TApartmentThread instance for each RemoteDataModule, and it's Execute method already processes messages:
while GetMessage(msg, 0, 0, 0) do
begin
DispatchMessage(msg);
Unk._AddRef;
if Unk._Release = 1 then break;
end;
I imagine to get this to process any custom message of mine, would mean re-writing the TApartmentThread Execute method.
I have confirmed that creating a window handle to process messages in a RemoteDataModule instance works using the technique described here:
http://delphi.about.com/od/windowsshellapi/a/receive-windows-messages-in-custom-delphi-class-nonwindowed-control.htm
This uses AllocateHWnd, which can be made thread-safe thanks to the work of others:
How can I make AllocateHwnd threadsafe?
Although this presents a solution, I would like to ask; is there a recommended alternative approach?
It would appear that the only other means of processing custom messages in a TApartmentThread instance would be to rewrite the Execute method.
Related
Let me give you a bigger picture of the problem... I am designing a ROS2-based system with multiple ROS2 nodes each containing a wrapper part (ROS2 layer) and driver/module part where my low-level logic is implemented. The wrapper part is using some ROS2-specific communication mechanisms (topics, services, actions...) to exchange the data/commands between the nodes.
Now, one of the nodes in the system should establish an MQTT connection with the Google Cloud Platform, keep the connectivity alive and allow data exchange between the Cloud and ROS2 system. For that purpose, I am using iot-device-sdk-embedded-c SDK from Google.
It has iotc_connect() blocking function for establishing and keeping connection with the Cloud so the challenge I am facing with is to simultaneously keep the ROS2 node spinning while keeping MQTT connectivity alive.
My idea was to launch a thread from ROS2 wrapper that will be used for establishing/keeping MQTT connectivity and use a callback function as an argument for the thread function that will enable me to forward the data received from the Cloud ithin the thread directly to ROS2 layer. Launching a separate thread for handling connectivity and data exchange would enable my ROS2 node to properly spin and rest synchronized with the rest of the ROS2 system.
ROS2_Wrapper.cpp
thread mqtt_thread(MqttConnHandler::ConnectToMqttServer, &MqttThreadCallback);
mqtt_thread.detach();
...
void MqttThreadCallback(void* data, size_t size){
}
MqttThreadCallback() should be called every time I receive the command/config data from the Cloud.
However, I am not sure how can I fire the callback function within the thread because I have two layers of nested callbacks within the thread:
my_thread.cpp
ConnectToMqttServer(void (*MqttThreadCallback)(void*, size_t)){
...
iotc_connect(...,&OnConnectionStateChanged);
...
}
OnConnectionStateChanged(...){
...
case IOTC_CONNECTION_STATE_OPENED:
iotc_subscribe(...,&iotc_mqttlogic_subscribe_callback,...);
...
}
iotc_mqttlogic_subscribe_callback(...){
//The place where data from the Cloud are received
}
iotc_connect() contains OnConnectionStateChanged() callback from where iotc_subscribe() function is called at the moment connection is established. iotc_subscribe() contains iotc_mqttlogic_subscribe_callback() where data from the Cloud are received.
I am not sure how can I mount the data from iotc_mqttlogic_subscribe_callback() up to the thread caller. Do you have any suggestions? Perhaps using the threads is not the best approach?
Usually C libraries provide an optional additional argument called user_data for this purpose:
extern iotc_state_t iotc_subscribe(iotc_context_handle_t iotc_h,
const char* topic, const iotc_mqtt_qos_t qos,
iotc_user_subscription_callback_t* callback,
void* user_data);
That way you can cast your callback function pointer to void when calling subscribe and catch it as argument in the iotc_mqttlogic_subscribe_callback function call. Where you should recast the data back to the function pointer type and use it.
In addition, you may find yourself in need to pass more data to the callback (mutex to protect the data, loggers from higher level code...). In that case, the best practice is to wrap all this info in a new class of your choice and pass a pointer to the instance in the callback.
We have recently started working on Typescript language for one of the application where a queue'd communication is expected between a server and client/clients.
For achieving the queue'd communication, we are trying to use the ZeroMQ library version 4.6.0 as a npm package: npm install -g zeromq and npm install -g #types/zeromq.
The exact scenario :
The client is going to send thousands of messages to the server over ZeroMQ. The server in-turn will be responding with some acknowledgement message per incoming message from the client. Based on the acknowledgement message, the client will send next message.
ZeroMQ pattern used :
The ROUTER/DEALER pattern (we cannot use any other pattern).
Client side code :
import Zmq = require('zeromq');
let clientSocket : Zmq.Socket;
let messageQueue = [];
export class ZmqCommunicator
{
constructor(connString : string)
{
clientSocket = Zmq.socket('dealer');
clientSocket.connect(connString);
clientSocket.on('message', this.ReceiveMessage);
}
public ReceiveMessage = (msg) => {
var argl = arguments.length,
envelopes = Array.prototype.slice.call(arguments, 0, argl - 1),
payload = arguments[0];
var json = JSON.parse(msg.toString('utf8'));
if(json.type != "error" && json.type =='ack'){
if(messageQueue.length>0){
this.Dispatch(messageQueue.splice(0, 1)[0]);
}
}
public Dispatch(message) {
clientSocket.send(JSON.stringify(message));
}
public SendMessage(msg: Message, isHandshakeMessage : boolean){
// The if condition will be called only once for the first handshake message. For all other messages, the else condition will be called always.
if(isHandshakeMessage == true){
clientSocket.send(JSON.stringify(message));
}
else{
messageQueue.push(msg);
}
}
}
On the server side, we already have a ROUTER socket configured.
The above code is pretty straight forward. The SendMessage() function is essentially getting called for thousands of messages and the code works successfully but with load of memory consumption.
Problem :
Because the behavior of ZeroMQ is asynchronous, the client has to wait on the call back call ReceiveMessage() whenever it has to send a new message to ZeroMQ ROUTER (which is evident from the flow to the method Dispatch).
Based on our limited knowledge with TypeScript and usage of ZeroMQ with TypeScript, the problem is that because default thread running the typescript code (which creates the required 1000+ messages and sends to SendMessage()) continues its execution (creating and sending more messages) after sending the first message (handshake message essentially), unless all the 1000+ messages are created and sent to SendMessage() (which is not sending the data but queuing the data as we want to interpret the acknowledgement message sent by the router socket and only based on the acknowledgement we want to send the next message), the call does not come to the ReceiveMessage() call back method.
It is to say that the call comes to ReceiveMessage() only after the default thread creating and calling SendMessage() is done doing this for 1000+ message and now there is no other task for it to do any further.
Because ZeroMQ does not provide any synchronous mechanism of sending/receiving data using the ROUTER/DEALER, we had to utilize the queue as per the above code using a messageQueue object.
This mechanism will load a huge size messageQueue (with 1000+ messages) in memory and will dequeue only after the default thread gets to the ReceiveMessage() call at the end. The situation will only worsen if say we have 10000+ or even more messages to be sent.
Questions :
We have validated this behavior certainly. So we are sure of the understanding that we have explained above. Is there any gap in our understanding of either/or TypeScript or ZeroMQ usage?
Is there any concept like a blocking queue/limited size array in Typescript which would take limited entries on queue, and block any new additions to the queue until the existing ones are queues (which essentially applies that the default thread pauses its processing till the time the call back ReceiveMessage() is called which will de-queue entries from the queue)?
Is there any synchronous ZeroMQ methodology (We have used it in similar setup for C# where we pool on ZeroMQ and received the data synchronously)?.
Any leads on using multi-threading for such a scenario? Not sure if Typescript supports multi threading to a good extent.
Note : We have searched on many forums and have not got any leads any where. The above description may have multiple questions inside one question (against the rules of stackoverflow forum); but for us all of these questions are interlinked to using ZeroMQ effectively in Typescript.
Looking forward to getting some leads from the community.
Welcome to ZeroMQ
If this is your first read about ZeroMQ, feel free to first take a 5 seconds read - about the main conceptual differences in [ ZeroMQ hierarchy in less than a five seconds ] Section.
1 ) ... Is there any gap in our understanding of either/or TypeScript or ZeroMQ usage ?
Whereas I cannot serve for the TypeScript part, let me mention a few details, that may help you move forwards. While ZeroMQ is principally a broker-less, asynchronous signalling/messaging framework, it has many flavours of use and there are tools to enforce both a synchronous and asynchronous cooperation between the application code and the ZeroMQ Context()-instance, which is the cornerstone of all the services design.
The native API provides means to define, whether a respective call ought block, until a message processing across the Context()-instance's boundary was able to get completed, or, on the very contrary, if a call ought obey the ZMQ_DONTWAIT and asynchronously return the control back to the caller, irrespectively of the operation(s) (in-)completion.
As additional tricks, one may opt to configure ZMQ_SND_HWM + ZMQ_RCV_HWM and other related .setsockopt()-options, so as to meet a specific blocking / silent-dropping behaviours.
Because ZeroMQ does not provide any synchronous mechanism of sending/receiving data
Well, ZeroMQ API does provide means for a synchronous call to .send()/.recv() methods, where the caller is blocked until any feasible message could get delivered into / from a Context()-engine's domain of control.
Obviously, the TypeScript language binding/wrapper is responsible for exposing these native API services to your hands.
3 ) Is there any synchronous ZeroMQ methodology (We have used it in similar setup for C# where we pool on ZeroMQ and received the data synchronously) ?
Yes, there are several such :
- the native API, if not instructed by a ZMQ_DONTWAIT flag, blocks until a message can get served
- the native API provides a Poller()-object, that can .poll(), if given a -1 as a long duration specifier to wait for sought for events, blocking the caller until any such event comes and appears to the Poller()-instance.
Again, the TypeScript language binding/wrapper is responsible for exposing these native API services to your hands.
... Large memory consumption ...
Well, this may signal a poor resources management care. ZeroMQ messages, once got allocated, ought become also free-d, where appropriate. Check your TypeScript code and the TypeScript language binding/wrapper sources, if the resources systematically get disposed off and free-d from memory.
My web server is based on Delphi / DataSnap.
When a server method raises an exception, how can I handle it?
I tried Application.OnException but it does not work because each connection is a new thread and it only works for the IDE thread.
I want to manage them for adding the data in a log file.
UPDATE:
As #Remy Lebeau says, I do not have control aver the creation of the thread. It is a DataSnap based application that works as Web Api server. A TDSServerClass components instances my TServerMethods class. Then, when a web connection arrives, DataSnap creates a new thread and call to my TServerMethods methods. If within the method, a exception is raised, then it is lost because each thread has its stack. With Application.OnException, I only can catch unhandheld exceptions from the IDE thread. What I want to do is to log any handheld exception in a log file.
From the System.Classes.TThread.FatalException documentation:
If the Execute method raises an exception that is not caught and handled within that method, the thread terminates and sets FatalException to the exception object for that exception. Applications can check FatalException from an OnTerminate event handler to determine whether the thread terminated due to an exception.
If an exception occurs in the Execute method of a TThread object its FatalException property is assigned and the thread terminates.
You can check if an exception occurred in a thread implementing its OnTerminate event:
procedure TForm1.YourThreadTerminate(Sender: TObject);
var
ex: Exception;
begin
ex := Exception(TYourThread(Sender).FatalException);
if Assigned(ex) then
//an exception has occurred: your code here
end;
This is how you can assign the event to you thread:
var
yourThread: TYourThread;
begin
yourThread := TYourThread.Create(True);
yourThread.OnTerminate := YourThreadTerminate;
yourThread.Start;
end;
You may need to hook into the exception handling mechanism itself - JCL has code that does that, for example, or you could use third party libraries like madExcept, EurekaLog or others. They also collect stack traces and other info useful to understand what lead to an exception.
I used JCL some time ago in a Datasnap DCOM server to log unhandled exception to a custom event log. If you're going to write to a file, beware of concurrent access, because more than one thread could try to write to it. Also Event Tracing for Windows (ETW) may be a a better, although more complex way, to log to a file for diagnostic purposes.
Anyway, in this kind of applications, it's better to handle "expected" exceptions, and never let them propagate up to a generic handler. Of course, being able to trap and log "unexpected" ones is useful.
I am trying solve this problem. I have WCF service. Client can call web method from this service which only "fire" another method (this method only write data to database) in another thread.
Code is here:
//this method will write data to database
public void WriteToDb()
{
}
//this web method will call only mehod WriteToDb() in another thread
public void SomeWebMethod()
{
new Task(WriteToDb).Start();
}
Problem is that in same time can web method call 5 clients. This cause that method WriteToDb is called 5 times in 5 thread.
In all 5 cases method WriteToDb will use same data.
My aim is achieve this behavior. 5 clients called web method SomeWebMethod. Method WriteToDb will run in 5 thread.
But I would like execute first thread, then second thread ....etc and on the end 5th thread.
I don’t want run method WriteToDb in same time in 5 thread.
So maybe I can use lock.
{
private object locker = new object();
//this method will write data to database
public void WriteToDb()
{
lock(locker)
{
//write to DB
}
}
I am not sure because .net assembly is host on app domain a app domain is host on win process. I woud like to avoid deadlocks.
What happens if I have a machine with 6 CPU? Use mutex instead lock ?
Thank you for help...
I'm not particulary sure what you are writing to DB, but your question is loosely coupled with WCF to be frank, try to read CLR via C# on multithreading etc.
Also regarding WCF, you can setup how your service object is created upon requests, ie per call, per session or singleton, and for later use specify if it's methods will stuck in queue or will be called on object concurrently.
So depending on choosing architecture you can either relay on WCF ability to host single object which will have logic you described or you can go the way tried.
Links
http://msdn.microsoft.com/en-us/magazine/cc163590.aspx
http://msdn.microsoft.com/en-us/library/ms731193.aspx
A lock is fine here, but you should make your locker object static so the same object instance is used in the lock every time.
It does not matter how many cores you have - if you hold the lock on an object then any other threads that attempt to acquire the lock will wait until the lock is released.
A deadlock can only occur if you are acquiring multiple locks in different orders in different threads.
I suggest you read Joe Albahari's excellent free ebook
I am writing a web service which has to be able to reply to multiple http requests.
From what I understand, I will need to deal with HttpListener.
What is the best method to receive a http request(or better, multiple http requests), translate it and send the results back to the caller? How safe is to use HttpListeners on threads?
Thanks
You typically set up a main thread that accepts connections and passes the request to be handled by either a new thread or a free thread in a thread pool. I'd say you're on the right track though.
You're looking for something similar to:
while (boolProcessRequests)
{
HttpListenerContext context = null;
// this line blocks until a new request arrives
context = listener.GetContext();
Thread T = new Thread((new YourRequestProcessorClass(context)).ExecuteRequest);
T.Start();
}
Edit Detailed Description If you don't have access to a web-server and need to roll your own web-service, you would use the following structure:
One main thread that accepts connections/requests and as soon as they arrive, it passes the connection to a free threat to process. Sort of like the Hostess at a restaurant that passes you to a Waiter/Waitress who will process your request.
In this case, the Hostess (main thread) has a loop:
- Wait at the door for new arrivals
- Find a free table and seat the patrons there and call the waiter to process the request.
- Go back to the door and wait.
In the code above, the requests are packaged inside the HttpListernContext object. Once they arrive, the main thread creates a new thread and a new RequestProcessor class that is initialized with the request data (context). The RequsetProcessor then uses the Response object inside the context object to respond to the request. Obviously you need to create the YourRequestProcessorClass and function like ExecuteRequest to be run by the thread.
I'm not sure what platform you're on, but you can see a .Net example for threading here and for httplistener here.