Why are these deferred tasks not being executed in the order in which they were added? - google-app-engine

I'm using Twilio to send sms's with appengine. Twilio doesn't accept sms's longer than 160 characters so I have to split them. I am splitting the sms's and sending them as follows:
def send_sms_via_twilio(mobile_number, message_text):
client = TwilioRestClient(twilio_account_sid , twilio_auth_token)
message = client.sms.messages.create(to=mobile_number, from_=my_twilio_number, body=message_text)
split_list = split_sms(long_message)
for each_message in split_list:
send_sms_via_twilio(each_message)
However I found that the order of sending varied. For example sometimes I'd recieve message 2/5 then 1/5 then 4/5 etc and other times the order would be correct. The order of the split_list is definately correct. To overcome the incorrect order of the sms's I tried
for each_message in split_list:
deferred.defer(send_sms_via_twilio, each_message, _countdown=1)
However I encountered the same problem. I then tried
for each_message in split_list:
deferred.defer(send_sms_via_twilio, each_message, _countdown=1, _queue="send-text-message")
and defined my queue as
- name: send-text-message
rate: 1/s
bucket_size: 10
max_concurrent_requests: 1
retry_parameters:
task_retry_limit: 5
Thinking that the issue was concurrency (running in python27) and that if I limited max_concurrent_requests this issue would be solved. However the issue is still present i.e. the texts still get sent in the wrong order. I checked the logs but couldnt see any notification of task failure - they just seem to be executing in the wrong order.
Is there something I am missing? How can I fix this issue.

Note that the SMS messaging (specifically the underlying protocols like SMPP) are asynchronous by definition. It means there is no way you can specify the order of distinct SMS messages.
There is a way to specify the order of SMS packets by using the UDH (user defined headers) in the binary body of those messages. But this works only for long SMS messages -- those that are too long to be sent in one message. For example, if your msg exceeds 160 GSM-7 characters or 80 UTF-16 characters it will be send as more than one message with UDH.
In that case the mobile phone won't show message parts as they arrive. It will collect them in memory until the last one comes and then assembles them in the right order. For the end user this is just a message longer than usual and you don't have to write "1/3", "2/3", ... in the message.
Disclaimer: I work for a company that enables you to send and receive both multiple binary messages with user-specified headers (UDH) and/or standard long messages.

If you are not tied to Twilio try using SMSified. They automatically split the message for you, insure it is in the correct order, and add "1/2, 2/2..." to the end of the message. In other words you just send the complete message to their REST API, no matter the length, and they handle the rest. Since they also use a REST API you can continue to use Python.

Related

Can I send an alert when a message is published to a pubsub topic?

We are using pubsub & a cloud function to process a stream of incoming data. I am setting up a dead letter topic to handle cases where a message cannot be processed, as described at Cloud Pub/Sub > Guides > Handling message failures.
I've configured a subscription on the dead-letter topic to retain messages for 7 days, we're doing this using terraform:
resource "google_pubsub_subscription" "dead_letter_monitoring" {
project = var.project_id
name = "var.dead_letter_sub_name
topic = google_pubsub_topic.dead_letter.name
expiration_policy { ttl = "" }
message_retention_duration = "604800s" # 7 days
retain_acked_messages = true
ack_deadline_seconds = 600
}
We've tested our cloud function robustly and consequently our expectation is that messages will appear on this dead-letter topic very very rarely, perhaps never. Nevertheless we're putting it in place just to make sure that we catch any anomalies.
Given the rarity of which we expect messages to appear on the dead-letter-topic we need to set up an alert to send an email when such a message appears. Is it possible to do this? I've taken a look through the alerts one can create at https://console.cloud.google.com/monitoring/alerting/policies/create however I didn't see anything that could accomplish this.
I know that I could write a cloud function to consume a message from the subscription and act upon it accordingly however I'd rather not have to do that, a monitoring alert feels like a much more elegant way of achieving this.
is this possible?
Yes, you can use Cloud Monitoring for that. Create a new policy and perform that configuration
Select PubSub Topic and Published message. Observe the value every minute and count them (aligner in the advanced option). Now, in the config, when it's above 0 from the most recent value, the alert is raised.
To filter on only your topic you can add a filter by topic_id on your topic name.
Then, configure your alert to send an email. It should work!

RxFrameNtf, TxFrameNtf and Ntf.data in unetpy

I am using Unetstack software along with Unetpy. I wish to retrieve transmit and recieve notifications when I run .py file which imports Unetpy python library. I followed this tutorial
I am successfully able to connect to the localhost and print values like phy.MTU and so on. When I transmit a packet I also receive a reply saying AGREE on the command prompt.output_of_my_script
my_script
Can you please help me in receiving Txframentf and rxframentf along with data payload.
I have made changes posted in bug reports suggested in this linkeven.
Please guide me on how to print notifications for rxframe and txframe.
Thank you``
Your script is fine until the last line:
print(phy << org_arl_unet_phy.TxFrameNtf())
Here you are trying to send a TxFrameNtf to the physical agent. This does not make sense, as it is the physical agent who sends you such a notification when a transmission is completed.
By the time you reach this line, you should have already received the notification as txntf as long as the transmission was completed within 5 seconds (timeout=5000). To print out the notification, all you need to do is:
print(txntf)
I just tested this against the 3-node-network.groovy sample. I am using unetpy-1.3b5 and fjagepy-1.4.2b3. Here's the modified code:
from unetpy import *
modem = UnetGateway('localhost', 1102)
phy = modem.agentForService(Services.PHYSICAL)
print(phy.MTU)
print(phy.basebandRate)
print(phy << org_arl_unet_phy.TxFrameReq(to=3, data=[1,2,3,4]))
txntf = modem.receive(timeout=5000)
print(txntf)
and the output:
16
4096
AGREE
TxFrameNtf:INFORM[type:1]
You can see that the TxFrameNtf is correctly received.
For reception, you need to subscribe to the agent's notifications and then receive a frame:
modem.subscribe(phy)
rxntf = modem.receive(org_arl_unet_phy.RxFrameNtf, timeout=5000)
print(rxntf)
Assuming you receive a frame within the 5 second timeout specified (in this example, on node 3), this should print out something like:
RxFrameNtf:INFORM[type:CONTROL from:1 to:3 protocol:0 rxTime:34587658 (4 bytes)]
You sent a datagram through some agent that supports the DATAGRAM service. There may be many agents that support this service (not just the physical layer). In any case, that datagram would be received on a different node, and so you wouldn't expect to receive DatagramNtf on the transmitting node.
The RangeReq should yield a RangeNtf if successful, but that might take more than the default receive timeout of 1 second, depending on how far node 2 is. So you might want to try a longer receive timeout to see if you get your notification.
To access the data from payload from the rxntf, you can try print(rxntf.data).

How to get partial results from Google App Engine's urlfetch?

When I'm using google.appengine.api.urlfetch.fetch (or the asynchronous variant with make_rpc) to fetch a URL that steadily streams data, after a while I will get a google.appengine.api.urlfetch_errors.DeadlineExceededError as expected. Since it is a stream that I want to sample, setting the deadline to a higher value can't ever help, unless the stream finishes (which I do not expect to happen).
It seems there is no possibility of getting the partially downloaded result. At least the API doesn't offer anything. Is it possible to
either request the downloaded part
or only ask for a certain amount of data (since I can estimate the stream's rate) to be downloaded?
[Clarification: Since it is a stream, requests with a Range header will be answered with 200 OK and not 206 Partial Content.]
In your call to urlfetch.fetch, you can set HTTP headers. The Range header is how you specify a partial-download request in HTTP:
resp = urlfetch.fetch(
url=whatever,
headers={'Range': 'bytes=100-199'})
if those are the 100 bytes you want. The HTTP status code you get should be 206 for such a partial download, etc (none of that's GAE-specific). See e.g http://en.wikipedia.org/wiki/Byte_serving for details.

How to remove default disclaimer in javamail

When sending emails via javamail, the following is always appended to the bottom of each message:
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager. This message contains confidential information and
is intended only for the individual named. If you are not the named
addressee you should not disseminate, distribute or copy this e-mail.
Please notify the sender immediately by e-mail if you have received
this e-mail by mistake and delete this e-mail from your system. If you
are not the intended recipient you are notified that disclosing,
copying, distributing or taking any action in reliance on the contents
of this information is strictly prohibited.
How does one prevent this?
(NOTE: This problem is extremely frustrating to research on the web due to the fact that a disclaimer of this form is attached to so many indexed documents! :-(
JavaMail is not doing that, it is your outgoing SMTP server appending it to each message, probably set up by IT.
To confirm, you can use gmail's servers (with a personal account) and you will see it does not get added to the messages.
This should work. Pay attention to the form in which email body get parsed. In my case the emailBody string is on one line, so you have to put the "#Your disclaimer Here#" on one line. Answer for who will come in future.
public String deleteDisclaimer(String emailBody) {
String disclaimer = "#Your disclaimer here#";
if (emailBody.contains(disclaimer)) {
System.out.println("Deleting Disclaimer..");
return emailBody.substring(0,emailBody.indexOf(disclaimer));
}
System.out.println("DISCLAIMER NOT FOUND!");
return emailBody;
}

How to use the binary push notifications format by C?

I use the The Push Notification Binary Interface cmd=2
This is format :
Q1: Can I send some device_id in one frame? For example:
item id = 1 , device_tocken #1
item id = 1 , device_tocken #2
item id = 1 , device_tocken #3
item id = 2 , message
item id = 3 ...
and etc
Q2: How I can receive the response error ?
The documentation said: If you send a notification that is accepted by APNs, nothing is returned.
If I make SSL_read after SSL_write and package was accepted by APNs, the program is waiting in SSL_read command.
r = SSL_write(ssl, out_buffer, size);
int len = SSL_read(ssl, in_buff, 6);
If I read from ssl channel into single thread - I have segmentation fault.
Q3: Do You know the link to example of use this protocol?
It's not clear from the documentation, but I don't think you can send multiple device tokens in the same frame, simply because if you get an error response of an invalid device token, you won't be able to know which device token it refers to. If, on the other hand, your frame contains a single device token and a single message identifier, then an error response containing that message identifier will tell you exactly which message caused the error.
You should use a non-blocking read for attempting to read the error response. I don't know how you write that in C, but there must be a way to specify some timeout or to call a read method that specifies a timeout. If there is nothing to read, the method will return after the timeout is elapsed.
The APNS docs contain samples for sending notifications in the older formats (0 and 1). I suggest you use format 1 (which supports error responses), since I don't see any advantage of using the newer format 2.

Resources