XSync - what does the discard parameter mean? - x11

According to the man page, calling XSync(dpy, 1) discards the events in the queue, but what does this really mean? If they are not discarded, are they sent twice (once by the XSync() call and a second time when the queue is emptied normally)? Or is it just like a garbage collector (the events get discarded anyway just a later time)?

XSync waits until the request output buffer is emptied (sent to the server). If the discard parameter is True, this function will throw away all queued events. These events are received from the X server.
Consider the following protocol exchange:
C -> S QueryKeymap request
C <- S ConfigureNotify event
C <- S QueryKeymap reply
You called XQueryKeymap in your client application which sents a QueryKeymap protocol message to the server. While doing so, you resized the window, hence the ConfigureNotify event.
If you run XSync(display, False) after your XQueryKeymap, then the client will wait until the reply is received. A next XPending(display) call will return the number of queued events which is 1 for the ConfigureNotify event above.
When XSync(display, True) was used instead, then XPending(display) returns 0 for the above case.
If your code is to be used by others, please save their time by not using True. For an example of what can go wrong when using True, see http://bugzilla.libsdl.org/show_bug.cgi?id=1859.

It's seems that you misconcept two things: X requests with X events, it's not the same. In short:
X requets:
... A client application sends requests to the X server over this connection. These requests are made by the Xlib functions that are called in the client application. ...
X events:
... Many Xlib functions cause the X server to generate events, and the user's typing or moving the pointer can generate events asynchronously. The X server returns events to the client ...
For more info check this - it's very helpful.
XSync called that way: XSync(dpy, False) does two things (according to manul that you pointed):
The XSync function flushes the output buffer and then waits until all requests have been received and processed by the X server.
XSync called that way: XSync(dpy, True) does those two things above plus additional one: discards (processes) all events in the queue.
If you passed True, XSync() discards all events in the queue, including those events that were on the queue before XSync() was called.
For example (pseudocode):
sendEvent2Xserver() //for example by pressing the key
endEvent2Xserver() //for example by mouse button press
XSendEvent() //sending chosen event to X server
XSync(dpy, True) // after this call, it's guaranteed that all the previous events were processed by the server

Related

Trigger/Handle events between programs in different ABAP sessions

I have two programs running in separated sessions. I want to send a event from program A and catch this event in program B.
How can I do that ?
Using class-based events is not really an option, as these cannot be used to communicate between user sessions.
There is a mechanism that you can use to send messages between sessions: ABAP Messaging Channels. You can send anything that is either a text string, a byte string or can be serialised in any of the above.
You will need to create such a message channel using the repository browser SE80 (Create > Connectivity > ABAP Messaging Channel) or with the Eclipse ADT (New > ABAP Messaging Channel Application).
In there, you will have to define:
The message type (text vs binary)
The ABAP programs that are authorised to access the message channel.
The scope of the messages (i.e. do you want to send messages between users? or just for the same user? what about between application servers?)
The message channels work through a publish - subscribe mechanism. You will have to use specialised classes to publish to the channel (inside report A) and to read from the channel (inside report B). In order to wait for a message to arrive once you have subscribed, you can use the statement WAIT FOR MESSAGE CHANNELS.
Example code:
" publishing a message
CAST if_amc_message_producer_text(
cl_amc_channel_manager=>create_message_producer(
i_application_id = 'DEMO_AMC'
i_channel_id = '/demo_text'
i_suppress_echo = abap_true )
)->send( i_message = text_message ).
" subscribing to a channel
DATA(lo_receiver) = NEW message_receiver( ).
cl_amc_channel_manager=>create_message_consumer(
i_application_id = 'DEMO_AMC'
i_channel_id = '/demo_text'
)->start_message_delivery( i_receiver = lo_receiver )
" waiting for a message
WAIT FOR MESSAGING CHANNELS
UNTIL lo_receiver->text_message IS NOT INITIAL
UP TO time SECONDS.
If you want to avoid waiting inside your subscriber report B and to do something else in the meanwhile, then you can wrap the WAIT FOR... statement inside a RFC and call this RFC using the aRFC variant. This would allow you to continue doing stuff inside report B while waiting for an event to happen. When this event happens, the aRFC callback method that you defined inside your report when calling the RFC would be executed.
Inside the RFC, you would simply have the subscription part and the WAIT statement plus an assignment of the message itself to an EXPORTING parameter. In your report, you could have something like:
CALL FUNCTION 'ZMY_AMC_WRAPPER' STARTING NEW TASK 'MY_TASK'
CALLING lo_listener->my_method ON END OF TASK.
" inside your 'listener' class implementation
METHOD my_method.
DATA lv_message TYPE my_message_type.
RECEIVE RESULTS FROM FUNCTION 'ZMY_AMC_WRAPPER'
IMPORTING ev_message = lv_message.
" do something with the lv_message
ENDMETHOD.
You could emulate it by checking in program B if a parameter in SAP memory has changed. program A will set this parameter to send the event. (ie SET/ GET PARAMETER ...). In effect you're polling event in B.
There a a lot of unknown in your desription. For example is the event a one-shot operation or can A send several event ? if so B will have to clear the parameter when done treating the event so that A know it's OK to send a new one (and A will have to wait for the parameter to clear after having set it)...
edited : removed the part about having no messaging in ABAP, since Seban shown i was wrong

Why are LINGER=0 and SNDTIMEO=0 used for Zyre actors' PAIR sockets?

Reviewing Pyre's (Python version of Zyre) source code, I saw the following:
def zcreate_pipe(ctx, hwm=1000):
backend = zsocket.ZSocket(ctx, zmq.PAIR)
frontend = zsocket.ZSocket(ctx, zmq.PAIR)
# ...
# close immediately on shutdown
backend.setsockopt(zmq.LINGER, 0)
frontend.setsockopt(zmq.LINGER, 0)
class ZActor(object):
# ...
def __init__(self, ctx, actor, *args, **kwargs):
# ...
self.pipe, self.shim_pipe = zhelper.zcreate_pipe(ctx)
# ...
def run(self):
self.shim_handler(*self.shim_args, **self.shim_kwargs)
self.shim_pipe.set(zmq.SNDTIMEO, 0)
self.shim_pipe.signal()
self.shim_pipe.close()
def destroy(self):
# ...
self.pipe.set(zmq.SNDTIMEO, 0)
self.pipe.send_unicode("$TERM")
self.pipe.wait()
self.pipe.close()
Interesting to me were the uses of LINGER=0 and SNDTIMEO=0.
The corresponding docs are here and here:
ZMQ_SNDTIMEO: Maximum time before a send operation returns with EAGAIN
[rather self-explanatory]
ZMQ_LINGER: Set linger period for socket shutdown
[...] The linger period determines how long pending messages which have yet to be sent to a peer shall linger in memory after a socket is closed with zmq_close(3), and further affects the termination of the socket's context with zmq_term(3). [...]
[...]
The value of 0 specifies no linger period. Pending messages shall be discarded immediately when the socket is closed with zmq_close().
[...]
So in short, the last message in both directions may not be sent. If send would block, SNDTIMEO=0 would kick in, and (presumably if there is still something in the send queue) LINGER=0 could discard the message during close.
That seems like a bad idea, because if $TERM is discarded, the actor isn't killed, and if the signal is discarded, the calling thread would just block. The only way it makes sense to me is if the messages may never be discarded (because of some characteristics of PAIR over inproc:// transport?), but then, why use the socket options in the first place?
What makes this code work as expected, why were the socket options used this way, and in what situation should/shouldn't I follow this example?
This looks like a latent bug (deadlock/hang) to me. If the actor doesn't read messages sent to it fast enough, the queue (with size 'hwm') could be full - meaning that zmq won't send anything, and the destroy() will end up waiting on a signal expected when the actor exits - but since the actor never receives "$TERM", it can't react - and unless there's a timeout in its recv(), it may wait forever for a message as well.
[ I notice there appears to be a skeptical comment just before the wait() in the destroy() method - so you may not be the first to notice this ]
I'd handle destroy() with care - practically speaking, you could code your solution so that overflowing the queue is highly unlikely - or you could check whether the send succeeds in destroy() - and if not - either try again (with timeout) or just skip the wait().

Implementing bulk-messaging from Salesforce to/from Twilio, hitting Salesforce API limits

I am building an integration between Salesforce and Twilio that sends/receives SMS using TwilioForce REST API. The main issue is getting around the 10-call API limit from Salesforce, as well as the prohibition on HTTP call outs from a trigger.
I am basing the design on Dan Appleman's Asynchronous Request processes, but in either Batch mode or RequestAsync(), ASync(), Sync(), repeat... I'm still hitting the limits.
I'd like to know how other developers have done this successfully; the integrations have been there for a while, but the examples are few and far between.
Are you sending unique messages for each record that has been updated? If not, then why not send one message to multiple recipients to save on your API limits?
Unfortunately, if you do actually need to send more than 10 unique messages there is no way to send messages in bulk with the Twilio API, you could instead write a simple application that runs on Heroku or some other application platform that you can call out to that will handle the SMS functionality for you.
I have it working now using the following structure (I apologize for the formatting - it's mostly pseudocode):
ASyncRequest object:
AsyncType (picklist: 'SMS to Twilio' is it for now),
Params (long text area: comma-separated list of Ids)
Message object:
To (phone), From (phone), Message (text), Sent (boolean), smsId (string), Error (text)
Message trigger: passes trigger details to CreateAsyncRequests() method.
CreateAsyncRequests: evaluate each new/updated Message__c; if Sent == false for any messages, we create an AsyncRequest, type=SMS to Twilio, Params += ',' + message.Id.
// Create a list to be inserted after all the Messages have been processed
List requests = new List();
Once we reach 5 message.Ids in a single AsyncRequest.Params list, add it to requests.
If all the messages have been processed and there's a request with < 5 Ids in Params, add it to requests as well.
If requests.size() > 0 {
insert requests;
AsyncProcessor.StartBatch();
}
AsyncProcessor implements .Batchable and .AllowsCallouts, and queries ASyncRequest__c for any requests that need to be processed, which in this case will be our Messages list.
The execute() method takes the list of ASyncRequests, splits each Params value into its component Message Ids, and then queries the Message object for those particular Messages.
StartBatch() calls execute() with 1 record at a time, so that each execute() process will still contain fewer than the maximum 10 callouts.
Each Message is processed in a try/catch block that calls SendMessage(), sets Message.smsId = Twilio.smsId and sets Message.Sent = true.
If no smsId is returned, then the message was not sent, and I set a boolean bSidIsNull = true indicating that (at least) one message was not sent.
** If any message failed, no smsIds are returned EVEN FOR MESSAGES THAT WERE SUCCESSFUL **
After each batch of messages is processed, I check bSidIsNull; if true, then I go back over the list of messages and put any that do not have an smsId into a map indexed by the Twilio number I'm trying to send them From.
Since I limited each ASyncRequest to 5 messages, I still have the use of a callout to retrieve all of the messages sent from that Twilio.From number for the current date, using
client.getAccount().getMessages('From' => fromNumber, 'DateSent' => currentDate)
Then I can update the Message.smsIds for all of the messages that were successful, and add an error message to Message.Error_on_Send__c for any that failed.

Block TCP-send till ACK returned

I am programming a client application sending TCP/IP packets to a server. Because of timeout issues I want to start a timer as soon as the ACK-Package is returned (so there can be no timeout while the package has not reached the server). I want to use the winapi.
Setting the Socket to blocking mode doesn't help, because the send command returns as soon as the data is written into the buffer (if I am not mistaken). Is there a way to block send till the ACK was returned, or is there any other way to do this without writing my own TCP-implementation?
Regards
It sounds like you want to do the minimum implementation to achieve your goal. In this case you should set your socket to blocking, and following the send which blocks until all data is sent, you call recv which in turn will block until the ACK packet is received or the server end closes or aborts the connection.
If you wanted to go further with your implementation you'd have to structure your client application in such a way that supports asynchronous communication. There are a few techniques with varying degrees of complexity; polling using select() simple, event model using WSASelectEvent/WSAWaitForMultipleEvents challenging, and the IOCompletionPort model which is very complicated.
peudocode... Will wait until ack is recevied, after which time you can call whatever functionallity you want -i chose some made up function send_data.. which would then send information over the socket after receiving the ack.
data = ''
while True
readable, writable, errors = select([socket])
if socket in readble
data += recv(socket)
if is_ack(data)
timer.start() #not sure why you want this
break
send_data(socket)

PostThreadMessage fails

I have created a UI thread. I m posting message to the UI thread which will write data in a file.
I am using PostThreadMessage API to post the message to User thread. My Problem is it's not writing all the data that I have posted. For Instance, if i post 100 data, it writes randomly 3 or 98 varies for every execution. The handler for Postdata is not getting called for every message.
CWriteToFile *m_pThread = (CWriteToFile *)AfxBeginThread(RUNTIME_CLASS (CWriteToFile));
PostThreadMessage(m_pThread->m_nThreadID , WM_WRITE_TO_FILE, (WPARAM)pData,NULL);
WaitForSingleObject(m_pThread, INFINITE);
The Return value of PostThreadMessage is success.
The PostMessage family of functions can fail if the message queue is full. You should check whether or not the function call succeeds.

Resources