How to allow rapid post requests on Google-App? - java

I'm setting up an android order taking application, and need to store the orders in google sheets. It works, but until I added the post request function in a for loop. So I fixed this by adding a delay in the for loop. However, is there any other way to do this? Because each time I submit an order the app lags until the for loop has finished.
I've added a thread.sleep to avoid this problem like so:
for (int i = 0; i < order.size(); i++){
String itemName = order.get(i);
String addOn = addOns.get(i);
String quantity = order.get(i);
quantity = quantity.substring(quantity.length() - 2, quantity.length() - 1);
itemName = itemName.substring(0, itemName.length() - 4);
System.out.println("Item ID: " + i + " " + itemName + " " + addOn + " " + quantity + " " + orderId );
try{
Thread.sleep(550); //This is the delay I added.
}catch(InterruptedException ex){
//do stuff
}
addItemToSheet(itemName,addOn,quantity,orderId);
}
if (null != getActivity()) {
((MainActivity) getActivity()).clearOrderList();
}
Here is the google app:
var ss = SpreadsheetApp.openByUrl("SPREADSHEET URL");
var sheet = ss.getSheetByName('Items');
function doPost(e){
var action = e.parameter.action;
if(action == 'addItem'){
return addItem(e);
}
}
function addItem(e){
var date = new Date();
var id = sheet.getLastRow();
var orderNum = e.parameter.orderNum;
var itemName = e.parameter.itemName;
var quantity = e.parameter.quantity;
var extra = e.parameter.extra;
sheet.appendRow([date,id,orderNum,itemName,quantity,extra]);
return ContentService.createTextOutput("Success").setMimeType(ContentService.MimeType.TEXT);
}
Is there anything I can do to either the java loop or google app, so I can avoid using thread.sleep which freezes my app until the operation is done? Maybe an alternative way to delay in java? or a faster operation in google apps?

In order to achieve what you want, I would recommend multi-threading.
Multithreading is a Java feature that allows concurrent execution of
two or more parts of a program for maximum utilization of CPU. Each
part of such program is called a thread. So, threads are light-weight
processes within a process.
This way your application will continue to run in a thread while you POST request is being handled in a different thread. Please bear in mind that in order to wait(), and notify() methods.
The methods above are used to control your workflow.
wait(): This method behaves exactly as if it simply performs the call wait(0).
notify(): This method wakes up a single thread that is waiting on this object's monitor.
More details about multi-threading in Java, here.
Here you shall find more details about the methods mentioned above.

Related

read mutiple characteristic from BLE and reading a string

So I have two question.
Let's start with the first one, how do you make two readCharacteristic after eachothers? the code I've showed is what I was thinking you could do it. But because onCharacteristicRead isn't called yet in the first readCharacteristic call the next readCharacteristic isn't triggered. Here i solved it by calling the second readCharacteristic in the if-statement for the first readCharacteristic in the onCharacteristicRead, but i don't know it this is normal/stupid solution?
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
BluetoothGattService mBluetoothGattService = gatt.getService(UUID.fromString(CSUuid));
if (mBluetoothGattService != null) {
Log.i(TAG, "Connection State: Service characteristic UUID found: " + mBluetoothGattService.getUuid().toString());
mCharacterisitc = mBluetoothGattService.getCharacteristic(UUID.fromString(UuidRead));
mCharacterisitc2 = mBluetoothGattService.getCharacteristic(UUID.fromString(UuidRead2));
Log.w(TAG, "Connection State 1: mCharacterisitc " + mCharacterisitc + " " + mCharacterisitc2);
readCharacteristic(gatt, mCharacterisitc);
//I know I have to wait for the above is done, but can I do it here instead of
//calling the line under in onCharacteristicRead?
readCharacteristic(gatt, mCharacterisitc2);
} else {
Log.i(TAG, "Connection State: Service characteristic not found for UUID: " + UuidRead);
}
}
}
Next question is a bit hard I think?
the code is made in PSoC creator 4.3
So at the moment I read a single int from my PSoC 6 BLE device, and another letter 'M' converted to a integer and back to a 'M' on the app-side. The reason I only read a SIGNLE 'M' is because I don't know how to send a whole string like 'Made it'. I think the issue I'm having is on the PSoC side where I don't know how to read a whole string.
for(;;)
{
/* Place your application code here. https://www.youtube.com/watch?v=Aeip0hkc4YE*/
cy_stc_ble_gatt_handle_value_pair_t serviceHandle;
cy_stc_ble_gatt_value_t serviceData;
//this is the variables I've declared earlier in the code
//static uint8 data[1] = {0};
//static char * ValStr;
//here I just have a simple Integer which count up every sec
serviceData.val = (uint8*)data;
serviceData.len = 1;
serviceHandle.attrHandle = CY_BLE_CUSTOM_SERVICE_DEVICE_OUTBOUND_CHAR_HANDLE;
serviceHandle.value = serviceData;
Cy_BLE_GATTS_WriteAttributeValueLocal(&serviceHandle); //sending the data to -> OUTBOUND
//this part should probably not be in a for-loop, but for now it is.
ValStr = "Mads Sander Hoegstrup"; //I want read whole string on my android APP
serviceData.val = (uint8*) ValStr; //this only takes the 'M' and thats the only variable I can read from my APP not the rest of the string
serviceData.len = 1; //Does not help to increase, if it's more than 1 I read 0 and not a letter
serviceHandle.attrHandle = CY_BLE_CUSTOM_SERVICE_DEVICE_OUTBOUND_2_CHAR_HANDLE;
serviceHandle.value = serviceData;
Cy_BLE_GATTS_WriteAttributeValueLocal(&serviceHandle); //sending the data to -> OUTBOUND_2
data[0]++;
CyDelay(1000);
}
Here you can see that I revice the right values, a Integer and a String, but only the letter 'M' and not the string 'Mads Sander Hoegstrup'
Just ask if you want more information
You'd better ask two separate questions, since they have nothing to do with each other.
I'll answer the first question. You cannot wait inside the onServicesDiscovered method between the two reads. Even if you wait for 30 seconds it will not work. The reason is that only one thread can run a callback on each BluetoothGatt object at the same time, and it's the caller of onCharacteristicRead that clears the internal gatt busy flag which otherwise prevents you from submitting another request. You'd better implement some queue mechanism to keep the code cleaner if you like.

I'm a very beginner at programming and need some help and advice

I need to write two programs. 1 sequential (Done) and 1 parallel and I've done something but i don't know if I've made it parallel or not and i also need to know:
If (Thread.State state = Thread.currentThread().getState();) is the code to display the status of a thread
how to assign different threads to different processors (4 cores)
How to display the status of the processor
calculation for each processor
how to generate error messeges(Memory Consistency Errors, etc.)
Following is my code:
class Threads implements Runnable {
#Override
public void run() {
Thread t = Thread.currentThread();
Thread.State state = Thread.currentThread().getState();
String Assignment = "calculations in array";
String name = "os.name";
String version = "os.version";
String architecture = "os.arch";
String[] array = new String[1312500];
int size = array.length;
Random r = new Random();
int[] values = new int[1312500];
int sumarray = 0;
int CountD = 0;
for (int i = 0; i < values.length; i++) {
int randomint = r.nextInt(100);
values[i] = randomint;
if ((values[i] % 2 != 0) && (values[i] >= 25 && values[i] <= 75)) {
sumarray += values[i];
CountD++;
}
}
System.out.println(t.getName());
System.out.println("Thread Id " + t.getId());
System.out.println("Thread Priority " + t.getPriority());
System.out.println("status " + state);
System.out.println("OS Name: " + System.getProperty(name));
System.out.println("OS Version: " + System.getProperty(version));
System.out.println("OS Architechture: " + System.getProperty(architecture));
System.out.println(Assignment);
System.out.println("Size of the Array is: " + array.length);
System.out.println("Total number of system cores(processors): " + Runtime.getRuntime().availableProcessors());
System.out.println("Difference of Array and Processors 1312500/4 = "
+ array.length / Runtime.getRuntime().availableProcessors());
System.out.println("The size of array is divisible by the number of processors");
System.out.println("Summary is: " + sumarray);
System.out.println("The Average is: " + (sumarray / CountD));
}
}
Main class:
class Concurrent {
public static void main(String[] args) {
Thread t1 = new Thread(new Threads());
t1.start();
Thread t2 = new Thread(new Threads());
t2.start();
Thread t3 = new Thread(new Threads());
t3.start();
Thread t4 = new Thread(new Threads());
t4.start();
}
}
[I need to know] If Thread.State state = Thread.currentThread().getState(); is the code to display the status of a thread.
That declares a variable named state and initializes it with the state of the thread in which it is executed. (https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.State.html
That code snippet doesn't display anything, but the subsequent System.out.println("status " + state); will write a representation of the state out to the console.
I have no way of knowing know whether Thread.State corresponds to what you call "status", but calling Thread.currentThread().getState(); yields no information because the state of any thread will always be RUNNABLE while it is calling getState().
[I need to know] how to assign different threads to different processors
I bet you don't.
What you are asking about is called "processor affinity." Most programs rely on the operating system to automatically schedule runnable threads on available CPUs. It's only very sophisticated programs (and note, "sophisticated" does not always equal "good") that need to tinker with it.
There is no standard way to set the CPU affinity of Java threads, but there might be some means that you can use on your particular operating system. You can google "Java processor affinity" for more info.
[I need to know] How to display the status of the processor
You're going to have to explain what "status" means and also, which processor, and when?
Depending on what "status" means, If you write code to ask for the "status" of the same processor that the code is running on, then the answer probably will never change. Just like how the result of Thread.currentThread().getState() never changes.
Processor "status" is the sort of thing that sysadmins of big data centers like to see plotted on charts, but they seldom are useful within a program unless, once again, you are doing something very sophisticated.
[I need to know] how to generate error messeges.
The simplest way to do that is to use System.out.println(...) or System.err.println(...)
Maybe you really meant to ask something else, like how to know when to report an error, or how to handle exceptions.
Most Java library routines throw an exception when something goes wrong. All you have to do in that case is completely ignore it. If you don't write any code to handle the exception, then your program will automatically print an error message and stop when the exception is thrown.
how to assign different threads to different processors (4 cores)
Let's leave this decision to java runtime. From programmer perspective, try to use the features available to you.
For effective utilizaiton of CPU cores, have a look at this question:
Java: How to scale threads according to cpu cores?
Regarding processor affinity, you can check posts:
Java thread affinity
http://tools.assembla.com/Behemoth/browser/Tests/JAVA/test/src/main/java/test/threads/ThreadAffinity.java ( written by BegemoT)
But you should avoid these type of things and focus on business logic.
how to generate error messeges(Memory Consistency Errors, etc.)
You can easily generate memory consistency errors.
Do not protect your code with thread safe constructs like synchronized or Lock and allow multiple threads to update data from your class.
Have a look at this documentation page
Refer to documentation links for better understanding of multi-threading concepts.

How should I parallelize a computationally expensive for loop and collate the iteration results?

I'm working on an 8-core machine and am performing a computationally heavy task. However, each execution of the task (i.e., iteration of for loop) is rather independent of the previous one. There are only some variables that are 'summed up' from one execution to the next. I'm guessing this is a good example for parallelizing/threading but I'm not sure how to go about it.
Here's how the code looks. As of now, it's just part of the main method in my main executor class:
double testerPayoffSum = 0.0, developerPayoffSum = 0.0;
Random seed = new Random();
try {
for (int i = 0; i < GameConstants.MAX_GAMES; i++) {
EraserSimulator eraser = new EraserSimulator(GameConstants.MAX_TARGETS, GameConstants.MAX_RESOURCES, GameConstants.NUM_ATTACKER_TYPES, seed.nextInt());
Map<Set<SingleObjectiveTarget>, Double> gameStrategy = eraser.run();
assert (gameStrategy != null);
TestingGameSimulator testingGame = new TestingGameSimulator(GameConstants.MAX_TARGETS, gameStrategy, GameConstants.NUM_GAMES_TO_STORE_FOR_HISTORY, GameConstants.NUM_TESTING_GAMES_TO_PLAY);
PlayerPayoffs payoffs = testingGame.run(eraser.getEraserInstance());
testerPayoffSum += payoffs.getAverageTesterPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
developerPayoffSum += payoffs.getAverageDeveloperPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
System.out.print("Output: ERASER Games played; Number of developers caught");
System.out.print(", " + GameConstants.NUM_TESTING_GAMES_TO_PLAY + ", " + payoffs.getNumTimesCaught() + "\n");
} catch(Exception e){sendEmailAlert("Execution Failed with Exception");}
I'd like to parallelize the for-loop computation if possible and keep summing up the testerPayoffSum and developerPayofffSum variables. How might I achieve this?
Note: Each execution of the for loop takes about 20-30 minutes depending on the input size (as set by the various GameConstants). Even for a small number of MAX_GAMES the above takes close to 2-3 hours.
Create a thread object implementing Callable which returns a Future object containing your testerPayoffSum and developerPayoffSum, start the calculation and sum the results obtained from the Futures (See also https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6).
are you absolutely sure you have no dependency ?
1.used classes must not share any variables
if it does then you have to add locks
but it will affect performance
if some shared variables are used extensively
then the performance can drop significantly even bellow the non-parallel execution
2.used classes must not use any kind of machine learning.
there is no solution for this
because parallelization will corrupt your results
Now how to do it (I am not JAVA coder so I stick to C++ code).
//--- globals and headers -----------------------------------------------------
unsigned long __stdcall function(LPVOID p);
Random seed = new Random();
const int N=8; // threads count (<=CPU count)
int id[N]; // thread id
int max[N]; // number of games per thread
double testerPayoffSum[N]; // sum to separate variables to avoid locks need
double developerPayoffSum[N];
volatile int run=0,stop=0; // thread control variables run is number of running threads and stop force stop...
//--- main code ---------------------------------------------------------------
// init some variables ... may be the seed init will be better here too
int i;
for (i = 0; i < N; i++)
{
id[i]=i;
max[i]=GameConstants.MAX_GAMES / N;
testerPayoffSum[i]=0.0;
developerPayoffSum[i]=0.0;
}
max[0]=GameConstants.MAX_GAMES % N;
// create threads
for (i = 0; i < N; i++)
{
HANDLE hnd=CreateThread(0,0,function,&id[i],0,0);
if (hnd!=NULL) CloseHandle(hnd); // this line is important !!!
// because if you do not close Handle it will be allocated until the end of app
// handle leaks are nasty and cause weird OS behaviour
// I saw many times this bug in commercial drivers
// it is a nightmare for 24/7 software
}
// wait for them
while (run) Sleep(200);
// sum the results to [0]
for (i = 1; i < N; i++)
{
testerPayoffSum[0] +=testerPayoffSum[i];
developerPayoffSum[0]+=developerPayoffSum[i];
}
// here do what you need to do with the results
//--- thread function ---------------------------------------------------------
unsigned long __stdcall function(LPVOID p)
{
run++;
int ix=((int*)p)[0];
for (i = 0; i < max[ix]; i++)
{
if (stop) break;
EraserSimulator eraser = new EraserSimulator(GameConstants.MAX_TARGETS, GameConstants.MAX_RESOURCES, GameConstants.NUM_ATTACKER_TYPES, seed.nextInt());
Map<Set<SingleObjectiveTarget>, Double> gameStrategy = eraser.run();
assert (gameStrategy != null);
TestingGameSimulator testingGame = new TestingGameSimulator(GameConstants.MAX_TARGETS, gameStrategy, GameConstants.NUM_GAMES_TO_STORE_FOR_HISTORY, GameConstants.NUM_TESTING_GAMES_TO_PLAY);
PlayerPayoffs payoffs = testingGame.run(eraser.getEraserInstance());
testerPayoffSum[ix] += payoffs.getAverageTesterPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
developerPayoffSum[ix] += payoffs.getAverageDeveloperPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
// do not call any visual stuff from thread !!! sometimes it can cause a lot of problems ...
// instead cretae some global string variable and set it to what shoud be printed out
// and inside wait while loop in main code add if string != "" then System.out.print(string);
// but in that case you should add lock to it.
// System.out.print("Output: ERASER Games played; Number of developers caught");
// System.out.print(", " + GameConstants.NUM_TESTING_GAMES_TO_PLAY + ", " + payoffs.getNumTimesCaught() + "\n");
//Sleep(100); // well placed sleep
}
run--;
}
[Notes]
from your code I am assuming that GameConstants is shared variable !!!
if it is only for read than it is OK
but if you do also write to it inside thread (I suspect that yes)
then you have a big problem because you need to add locks inside your game class then ...
if no machine learning is done then you could avoid this
by creating separate GameConstants variables for each thread like ... GameConstants[N]
but you need to rewrite the code so it access the GameConstants[ix] and not GameConstants
[lock]
have no clue how locks are implemented in JAVA
but you can also use your own something like this
class _lock
{
public:
volatile bool locked;
_lock() { locked=false; }
void lock() { while(locked) Sleep(1); locked=true; }
void unlock() { locked=false; }
};
// now for each shared variable (or group of variables) add one global _lock variable
_lock l1; int sv1; // shared variable 1 and her lock
// any write access and sometimes also read access needs lock
l1.lock();
sv1++;
l1.unlock();
beware that locks can sometimes cause App freeze especially while heavy duty use.
does not matter if it is own lock or OS lock
this occurs mainly while mixing visual stuff or some OS calls inside threads and not in main thread
in that case sometimes a well placed sleep helps but avoid OS calls inside threads if you can
because it cause very many other problems ...
also try to be locked as small time as possible because in case of conflict the conflicting threads are stopped !!!
therefore you cannot just add lock at the start of loop and unlock at the end
because the parallelism speedup will be lost then
Declare a queue to collect results and submit tasks to a thread pool:
final ArrayBloclingQueue<PlayerPayoffs> queue=new ArrayBloclingQueue<PlayerPayoffs>();
Executor exec=new Executors.newFixedThreadPool(N); // number of threads depends on hardware
for (int i = 0; i < GameConstants.MAX_GAMES; i++) {
exec.execute(new Runnable(){
EraserSimulator eraser = new EraserSimulator(GameConstants.MAX_TARGETS, GameConstants.MAX_RESOURCES, GameConstants.NUM_ATTACKER_TYPES, seed.nextInt());
Map<Set<SingleObjectiveTarget>, Double> gameStrategy = eraser.run();
assert (gameStrategy != null);
TestingGameSimulator testingGame = new TestingGameSimulator(GameConstants.MAX_TARGETS, gameStrategy, GameConstants.NUM_GAMES_TO_STORE_FOR_HISTORY, GameConstants.NUM_TESTING_GAMES_TO_PLAY);
PlayerPayoffs payoffs = testingGame.run(eraser.getEraserInstance());
queue.put(payoffs);
});
}
Then collect and sum results:
double testerPayoffSum = 0.0, developerPayoffSum = 0.0;
for (int i = 0; i < GameConstants.MAX_GAMES; i++) {
PlayerPayoffs payoffs=queue.take();
testerPayoffSum += payoffs.getAverageTesterPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
developerPayoffSum += payoffs.getAverageDeveloperPayoff(GameConstants.NUM_TESTING_GAMES_TO_PLAY);
System.out.print("Output: ERASER Games played; Number of developers caught");
System.out.print(", " + GameConstants.NUM_TESTING_GAMES_TO_PLAY + ", " + payoffs.getNumTimesCaught() + "\n");
}

sleep in Java web application

I want to use Thread.sleep() in my java application. But does not work. Program works after removing sleep.
In my program I am running multiple threads and want that each move forward at a variable speed. Some may get executed more some less. So I am using sleep in each with a random number as argument.
If there another way to do this. Without using sleep.
Here is the part where I am using the sleep function.
public void run()
{
Random r = new Random();
int t;
while(true)
{
if(total == 1)
{
// win();
break;
}
if(doa == 1)
break;
// Player x = e[r.nextInt(20)%2];
Player x = choose();
x.attack(this, 10 + (power==1?5:0));
if(r.nextInt(100)%(5 - (power==2?2:0)) == 0)
System.out.println(" " + name + " used Potion effect (" + potionno++ + ") .. now " + name + "'s Health is " + (h+= 10 + r.nextInt(20)));
try
{
sleep(50 + r.nextInt(1000));
}
catch(InterruptedException c)
{ ; }
}
if(doa == 1)) {
// and so on
.
.
and here is my doGet function used for initiation
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String s;
s = request.getParameter("name");
try{
Player.out = out;
Player.e[0] = new Player("Kartik",2);
Player.e[1] = new Player(s,1);
Player.e[2] = new Player("Anirudh",3);
Player.e[3] = new Player("Vinita");
Player.e[4] = new Player("Shivank");
for(Player p: Player. e)
p.start();
}
catch(Exception e)
{
out.print("WRONG");
}
}
You shouldn't do that since, in general, Java EE/servlet containers work on the assumption their applications do not spawn threads (or modify the execution or configuration of existing ones, which you are doing with Thread.sleep()) of their own all nilly willy.
It is possible, but generally frowned upon unless you know what you are doing. See this answer that succinctly but excellently explains why: https://stackoverflow.com/a/533847/201722
As of why your call to Thread.sleep() doesn't work, it is because your servlet container is multi-threaded. Your call to Thread.sleep() is simply putting the thread that is handling your current HTTP request to sleep. But the container is still alive and kicking. If you send another HTTP request, it will grab another thread distinct from the one you put to sleep to handle it.
So, from your POV, it looks like it is not working. But it is working, you put the poor thread to sleep, and the container goes ok, here is another one for you. It just so happens you don't know what the heck is going on.
I would suggest you take the time to go through both the Java and the Java EE tutorials made available by Oracle (former Sun.) Google it and you will find it.
== EDIT ==
I would also recommend the OP to read the following succinct explanation against indiscriminately meddling with threads in a container.
http://www.psionicwave.com/blog/2012/12/15/threading-in-web-containers/
Many things are wrong with your current approach, I'll try to point out some.
Your Player apparently extends Thread. That's an antipattern; you should only implements Runnable and pass the instance of your class to new Thread();
the basic flavor of a Servlet-based Web application is based on a strict request-response paradigm, where the respone happens as soon as possible. What you (possibly) are looking for is a "long response", asynchronous style. This can be achieved with new features in Servlet 3.0, but is well beyond the scope of this answer;
assuming for a moment that you just want a go at it, a quick patch is to append
for (Player p : Player.e) p.join();
to your existing doGet method. This will postpone the returning of doGet until all your subthreads die. You will also need to routinely flush the writer to force the immediate sending of the data to the client side (or use PrintWriter#println, which has auto-flush semantics).

App Engine Datastore - Incrementing property increments by 2

I'm trying to build out a simple app engine datastore entity that basically keeps count of how many times it was viewed. I've got the code setup in a JSP file that does increment the variable, however every time it seems to increment by 2 rather than one. Here's the code in question.
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Entity story = datastore.get(KeyFactory.stringToKey(request.getParameter("story_key")));
String json_out = "";
int num_views = 0;
if(story.getProperty("views") != null) {
num_views = Integer.parseInt(story.getProperty("views").toString());
}
//Update the donated status of this object.
story.setProperty("views", num_views + 1);
datastore.put(story);
json_out += "{";
json_out += "\"title\":\"" + story.getProperty("title") + "\", ";
json_out += "\"views\":\"" + num_views + "\"";
json_out += "}";
out.println(json_out);
Any idea why it would be incrementing by 2? I've even tried subtracting one when I get the number of views, but then the number just stays the same all the time as you'd expect. Really odd.
If you are implementing a counter using the datastore, you should you techniques that allow for high throughput. Your solution above could easily write to the datastore more than a few times per second, violating HRD policies. Also, it's not thread safe (not run in a transaction, so updates could apply out of order and your result is not what you expect). Try out shard counters, which fix these issues:
http://code.google.com/appengine/articles/sharding_counters.html

Categories

Resources