To separate value of a variable between multiple logged in web users

H I :

I have made a progress bar in my jsp page, showing the progress of [upload excel file -> extract the data from excel file to java variables -> using those variables, create .mp4 file -> once file made, insert into DB]

How I made it before was:

state private string xxxx in serviceImpl and make getter/setter there, and from controller, bring the data value by using

serviceImpl.getVARIABLE(); 

(this worked as ajax from jsp with interval)

It worked. But it only worked fine when the logged in user was singular.

If there were 2 users logged in at the same time, uploading different files,for example the progress bar had to look like

  • for user A: [7/999] ing . . . .
  • for user B: [92/923123] ing .. .

but instead of that, the variable got synchronized and works like

  • for user A: [7/999] ing . . . .
  • for user B: [7/999] ing . . . .

and the progress hits error and it finishes the method without work being done.

And i realized its very obvious and my code was so stupid cause i literally just stated the variable in serviceImpl field and kept using setter/getter.

So i deleted the stated variables from serviceImpl and added HttpSession session in methods, using

session.setAttribute("xxx", xxx);

and get the value of the variable from controller with

session.getAttribute("xxx");

it worked AGAIn with onLY ONE USER . I spent all day changing it and when it didnt work i finally realized its obvious, too. cause How could my code know that my session.setAttribute 's session is from user A or B when they both are logged in ....

So i have faced a wall and i came to ask for help. How should i manage to differentiate the variables between user A and B?

controller:

inside method A:

 a = (int) session.getAttribute("currentStateCount");
 b = (int) session.getAttribute("totalRowCount");

serviceImpl:

inside method B:

 session.setAttribute("currentStateCount", 12+);

inside method C:

  session.setAttribute("totalRowCount", total);

How should I work with my code to prevent from variables to synchronize between different users? Im so sorry if my question or my java skill is too stupid.. also sorry for bad english. Please help me, thank you.


Hello, i have just realized its not a problem with my progress bar.

My file uploading, extracting, inserting methods from serviceImpl does not support two files at one time.

When user A is uploading a file and user B starts uploading in the middle, it wont accept user B and it waits till user A is done and sends JDBC connection error to user B. So in the end only the one who started first's file upload would work. Im so sad, is there any way that i can fix this??

Wisthler :

The issue looks related to the implementation of ServiceImpl which is processing only one item at a time.

From that point, I see three solutions:

  1. Add a "isBusy()" on ServiceImpl and refuse new request until the exist one has been processed. Not really user friendly but should not be too difficult to implement
  2. Change the scope of ServiceImpl to have several instances. Session scope should solve part of the issue but you will still have to manage the fact that the same user in the same session can submit several files. Which can be forbidden using solution 1 which now make more sense :)
  3. Improve ServiceImpl to manage many files (would be good to put a limit on it, so again using solution 1 in addition here would be good :)) but then you need to update the methods to specify for which of the files you want a feedback/result

Without more details of the ServiceImpl, it's hard to come with examples for those solutions and confirm which one is actually the best one.

Edit: adding a skeleton example on what I'm expecting is in your ServiceImpl with the solution 3 implemented in it.

import java.io.File;
import java.util.HashMap;
import java.util.Map;

class Scratch {
    public interface Worker{
        public void process(File file);
        public int getStatus();
        public int getTotal();
    }

    public class ServiceImpl{
        Map<File, Worker> workers = new HashMap<>();
        private static final int MAX = 10;

        public void process(File file){
            if(workers.size() < MAX) {
                Worker worker = null; // replace by actual implementation :)
                workers.put(file, worker);
            }else{
                throw new ArrayIndexOutOfBoundsException("max number of simultaneous operations reached, try again later");
            }
        }

        public int getStatus(File f){
            return workers.get(f).getStatus();
        }

        public int getTotal(File f){
            return workers.get(f).getTotal();
        }

        public void clean(File f){
            Worker worker = workers.get(f);
            if(worker.getStatus() == worker.getTotal()){
                workers.remove(worker);
            }else{
                throw new UnsupportedOperationException("process is not over, cannot clean it");
            }
        }


    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=141236&siteId=1