How to implement an atomic integer in Java App Engine? - java

I am trying to roll out my own SMS verification system for my app. I don’t want to start paying for a service and then have them jack up the price on me (Urban Airship did that to me for push notification: lesson learned). During development and beta testing I have been using Twilio with a very basic setup: 1 phone number. It worked well for over a year, but right now for whatever reason the messages aren’t always delivered. In any case I need to create a better system for production. So I have the following specs in mind:
600 delivered SMS per minute
zero misses
save money
Right now my Twilio phone number can send one SMS per second; which means the best I can handle is 60 happy users per minute. So how do I get 600 happy users per minute?
So the obvious solution is to use 10 phone numbers. But how would I implement the system? My server is App Engine, DataStore, Java. So say I purchase 10 phone numbers from Twilio (fewer would of course be better). How do I implement the array so that it can handle concurrent calls from users? Will the following be sufficient?
public static final String[] phoneBank = {“1234567890”,”2345678901”,”3456789012”,”4567890123”,…};
public static volatile nextIndex;
public void sendSMSUsingTwilio(String message, String userPhone){
nextIndex = (nextIndex+1)%phoneBank.length;
String toPhone = phoneBank[nextIndex];
// boilerplate for sending sms with twilio goes here
//…
}
Now imagine 1000 users calling this function at the very same time. Would nextIndex run from 0,1,2…9,0,1…9,0,… successively until all requests are sent?
So really this is a concurrency problem. How will this concurrency issue work on Java AppEngine? Will there be interleaving? bottlenecking? I want this to be fast on a low budget: At least 600 per minute. So I definitely don’t want synchronization in the code itself to waste precious time. So how do I best synchronize calls to increment nextIndex so that the phone numbers are each called equally and in a periodic fashion? Again, this is for Google App Engine.

You need to use Task API. Every message is a new task, and you can assign phone numbers using round-robin or random assignments. As a task is completed, App Engine will automatically pull and execute the next task. You can configure the desired throughput rate (for example, 10 per second), and App Engine will manage the required capacity for you.
You can try to implement something similar on your own, but it's much more difficult than you think - you have to handle concurrency, retries, instance shutdowns, memory limits, etc. Task API does all of that for you.

Related

Discord bot - delay when sending messages [duplicate]

I want my discordbot to send send a message with an attached file in it and a text. Then the bot has to edit this text a couple of times but the problem is that when bot eddits message 5 times then it waits some time and then edits again 5 times etc etc. How can i make it edit messages without stopping?
if(msg.content.includes("letter")){
msg.channel.send("alphabet", { files: ["/Users/48602/Videos/discordbot/aaa.png"]})}
if(msg.content === 'alphabet'){
msg.edit("**a**")
msg.edit("**b**")
msg.edit("**c**")
msg.edit("**d**") // Here bot stop for a 2 seconds and i dont know why
msg.edit("**e**")
msg.edit("**f**")
msg.edit("**g**")
msg.edit("**h**")
msg.edit("**i**")
msg.edit("**j**")// Here bot stop for a 2 seconds and i dont know why
msg.edit("**k**")
msg.edit("**l**")
msg.edit("**m**")
msg.edit("**n**")
msg.edit("**o**") // Here bot stop for a 2 seconds and i dont know why
msg.delete()
}
Discord has a rate limit of 5 in each request. Trying to bypass this would be considered API abuse (the solutions later is not API abuse).
Exceeding this limit will pause other requests until a certain number of seconds has passed. Along with my research, I came across this simple explanation:
5 anything per 5 seconds per server (if you did not understand what I said above).
On Discord's Developer guide on rate limits, it tells you this:
There is currently a single exception to the above rule [rate limits] regarding different HTTP methods sharing the same rate limit, and that is for the deletion of messages. Deleting messages falls under a separate, higher rate limit so that bots are able to more quickly delete content from channels (which is useful for moderation bots).
One workaround, without API abusing, would be to send messages, and delete the previous messages since there is a higher limit for deleting messages.
Another workaround would be to add intermediate timeouts to your animation.
A simple method such as:
function async wait = { require("util").promisify(setTimeout); };
//syntax: await wait(1000); to "pause" for 1 second
You will need to play around with the timings so it fits your intended animation speed, and without pausing due to the rate limit.

Syncing Two Metronomes In Java using Bluetooth for Android

I have a bit of a unique issue. I'm collaborating with several other Computer Science Majors at my university on an Android Metronome app that allows two users with the app to sync metronomes. Right now, I can send the desired beats per minute of the metronome from one phone to the other and both phones will start to play their respective metronomes. Due to the latency of Bluetooth, the metronomes are only in sync about 20% of the time.
So, here's where the problem is. We're trying to make it so both of the metronomes will start at the exact same time. One way I've thought of doing this is once the first user presses the send button on their phone, a time stamp will be created. This time stamp will be exactly two seconds after the user presses the send button. The time stamp will then be sent to the second phone and the phone will utilize this time stamp to start it's metronome at the same exact time as the first phone. I've tried accomplishing this by putting UTC time in a while loop and then constantly checking the time, to no avail. Does anyone have any ideas as to how we can go about implementing this? I couldn't find any similar problem on StackOverflow, or any other website for that matter.
It's a bit late probably for your project, but if interested. This is a bit long, it's more like a case study.
If your project was about syncing two device clocks remotely, then this won't help you, but if it was about syncing the metronomes, then this may be a start.
First, getting millisecond accurate timings and callbacks in android using java is next to impossible, since android is not a real time system ( All sleep methods and timer might not execute on the exact millisecond you're expecting ). You may want to go with NDK for triggering your beat events, because native threads in android can achieve that, but if you're happy with your single metronome implementation, then that's good enough to read the rest of this .
Full disclosure :
I am the author of JAM the app referenced in the answer I just published a few days ago.
I ran into the same problem when developing the app.
And whether this answer will help you or not, depending on your situation.
and if you're going down the "clock sync" route ( Which I do plan on exploring to improve my app down the road with more features ) but the solution that I found did not involves time sync.
I will mention my approach and then state what I found as advantages/disadvantages for each of the methods .
Instead of syncing clocks ( A very difficult problem, especially for what the app was supposed to do , and that is trigger ticks on multiple devices at the "same" time ) I opted for a subscribe/publish model, where multiple devices can "subscribe" to a host device via bluetooth, and the host device controls and "publishes" the metronome beats.
most times sending a few hundred bytes ( Enough information about each beat ) via bluetooth takes less than 2ms , it could spike up to 10 and sometimes even 30, but that rarely seems to happen .
That approach took care of the syncing problem, now I can send beat events from one device to another in 2ms , and if some sort of delay happened, it will self correct once the interference is gone, because the other event comes in time.
However that approach does require constant connection, you can't start and separate the devices later on, but it's much easier to implement.
Now the interesting part, the problem I never thought of when starting this, and that was the Android 10 millisecond audio path latency problem. I'm not affiliated with superpowered, but I did use their engine in my app to deal with that problem .
To summarize :
Metronome sync over bluetooth in Android has two issues :
1 - triggering beat events simultaneously ( or within acceptable latency )
2 - The beat event should trigger sound events with minimal delay after the beat event is received
#1 is related to the original question, #2 I thought was an important addition to the original problem this question is asking.
I would use (S)NTP to check the clock drift to a public time server. After that I would just send the interval and a start time and let the devices calculate the interval individually. So you just need to sync changes and relay on the clocks of the individual devices. Together with the now known clock drift you can fix this error.

Configure app engine push task queue for twilio SMS verification

This question is a follow up to How to implement an atomic integer in Java App Engine?. Basically I am create a push Task Queue to implement SMS verification. I am using Twilio to send the SMS. Each SMS is a five digit pin number. The following is my queue.xml file for app-engine.
<queue-entries>
<queue>
<name>sms-verification</name>
<rate>200/s</rate>
<bucket-size>100</bucket-size>
<max-concurrent-requests>10</max-concurrent-requests>
</queue>
</queue-entries>
I want the best rate I can get without creating a new instance. I believe instance creation is expensive on app-engine, though I am not sure if it's the same for task queues. So is this configuration file good? Is it missing anything? This is my first time creating one so thanks for any guidance.
There is no right or wrong answer to this question. You will have to play with the configuration settings to get the optimal results for your requirements. You need to take the following into account:
You load throughout the day/week: more or less even or with sharp peaks.
Delay tolerance: how long it is acceptable to wait until the message is sent.
Obviously, it will be more expensive if you want to send all messages immediately, and less expensive if you can tolerate even a small delay (e.g. 1 minutes) as it would smooth out at least some sudden peaks.
Note that the higher the volume, the less important these optimizations become, as 1 new instance over 20 live is not as expensive as 1 new instance over 1.

How to have timelimits with Netty?

I am looking at using netty to implement a server for an AI bot competition. The chat example is a good start since the protocol I have designed is similar to a line based chat server, except for one major difference. The bots are asked to make a turn and have a maximum time limit to respond. If a bot fails to respond in time, the server will take a default action for that bot.
In particular I'm implementing The Resistance game. A leader will pick a team and then all the bots have to submit a yes or no vote. I want to wait until either all bots have voted or a timeout (eg. 2 seconds) occurs, in which case I will assign an action for the bots that have yet to respond.
How can I implement this using Netty?
My solution to this problem is to have a Game object running on a thread that uses CountDownLatch to wait upto the timelimit and collects all the votes from the Netty handlers. Any missing votes are given a default vote.
If I want to avoid having a thread for each game, I have built a Fiber library which provides cooperative lightweight threads. Then each Game object can be a fiber load balanced between a thread per CPU core.

Multiple threads to comunicate with multiple sensors

I am new to threads. I want to communicate with multiple sensors at one time after every minute continuously 24/7.
Senario:
I have a method to talk to the sensors which takes 3 arguments
public String perform(String command, String ip, String port)
{
//talk to the sensor and then
returns reply;
}
I have a database that contains the details of the sensor.
What I'm doing right now
while(true)
{
//get sensors from database
//run perform method for all instruments
for(int i=0;i<sensors.length-1;i++)
{
//call perform method and save the reply
}
Thread.sleep('one minute');
}
Problem:
The problem is if I have 100 sensors and each sensor takes 1 second to reply then after that I will be waiting for 1 minute, in this case I may lose some information. And to be honest sometime It takes more than a second to respond.
What I want to do is, get the information from the database for all the sensors
then create one thread for each sensor. Then run all the threads at one time which will return me some information. After that wait for one minute then do it again.
Any help is appreciated.
Thanks
Have you looked at the ScheduledThreadPoolExecutor ?
A simple usage would be to create a Callable for each of your sensors, and configure the thread pool to contain as many threads as you have sensors. Then submit each Callable, specifying an appropriate schedule.
Note that this approach doesn't guarantee particularly accurate timings (Java's not by any means a real-time platform). The other issue is that creating a lot of threads can be relatively memory-hungry (IIRC the standard heap allocation per thread is 512k, but it's configurable) and this approach wouldn't scale if you had 1000s of sensors.
Personally I would take a different approach. I would have the server always listening via a RESTful API and then have the sensors POST their state every minute (or other interval you decide). This way the server and the sensors don't need to be within the same JVM and IMHO is more scalable. Also, this way any sensor can also query for the state of any other sensor via another RESTful API on the server.
Additionally the server can start a thread to handle each POST and if one sensor is taking very long, the others are not blocked.

Categories