Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    How to handle concurrent users?

    Hi there,

    It was already adressed briefly but without an answer (Thread 1578)

    I'm building an interface for an admin gui of a web shop, where you can edit all the data.
    Since there are multiple users, users potentially might be logged in the whole day and never refresh the site, so they won't get any updates other users entered.

    Scenario:
    User1 edits the list of distributors.
    User2 is entering a new product (where he can select a distributor), but since his datasource of distributors was loaded before User1 edited these, he won't see the changes.
    In the worst case he wont ever see the distributor unless he hits reload in the browser.

    Generally I don't destroy any "pages", once loaded they stay (using tabs or a navigation). While it's no problem with users searching through lists (a fetch needed), it is with small datasources where the whole List is loaded only once.
    Users might sit right next to each other and wonder why they don't see the same data.
    Unless i provide an "refresh" button they can only reload the whole app to refresh the lists, since "paging" is in fact only displaying another tab an there is no server roundtrip involved.
    In an traditional webapp, a reload of a page or simply navigating would solve that problem.

    What do you suggest to solve such problems?

    The solutions I've come up with:
    - auto refresh. Not very beautiful and for a certain amount of time the data is out of date
    - refresh button. Would need the users to actively do something.
    - reload datasources everytime a page is accessed.
    - server push notification. Sounds quite cool but no experience so far
    - ...?

    when i think about it: is it a good idea to use a datasource "distributor" for the editable list AND the mask where users can enter products?
    If I'm to use two DS, the problem even arises for a single user, since his second DS won't reflect the changes until I reload it. Indeed, it's simple but I need to handle all the links explicitly.

    #2
    Even traditional web applications have this problem over short periods - the data is stale until the user navigates, and stale pages may be present in the cache.

    Solutions are:
    1) optimistic concurrency: catch the problem when the user tries to save (use dsRequest.oldValues to detect staleness)

    2) periodic refresh

    3) continuous updates via SmartGWT Messaging (exists for SmartClient, coming soon for SmartGWT)

    Comment


      #3
      First: Thanks for your answers.

      the optimistic strategy does only prevent saving entities with links to already deleted objects, not with the gui missing new or changed items. But yes, it's important for data integrity. I'll keep that in mind.

      well, messaging is for the Enterprise Edition, right?
      I can't afford anything but my manpower, since it's a university project with (surprise surprise) no budget.

      I'll try the refresh and probably implement an last updated timestamp to check against when a mask gets the focus.


      BTW: great job guys, keep going! :)

      Comment


        #4
        Hi,

        I have the same situation.

        User A selects a category and adds a new item. The new item does not appear on user B's listGrid. So user B might add the same data, thinking it's not there.

        I'm using LGPL with PHP/MySQL.

        I'm trying to think of a way to update user B's listGrid automatically, either with the new record, or a least a little flag to pop up that user A is currently in the same category or record.

        I'm thinking that when A selects the category or item, I can insert a record into an "activity" table with the user's id, the id of the widget they interacted with, the id of the record selected, and a timestamp.

        I think JavaScript has a timer mechanism that I can use to query the "activity" table every minute or so.

        So when B is on a phone call, the timer can update some element on his screen to indicate that another user has done something with that window element.

        farmer, is this what you were thinking?

        Would it be possible to subclass each widget to include it's own timer?

        Maybe that would generate too much network traffic and hits to the database.

        Anybody have any better ideas?

        Is there any way to do push with LGPL version and PHP?

        Thanks,
        Mike

        Comment


          #5
          The following may be of interest to people watching this thread:

          The Messaging module has still not been officially ported to SmartGwt EE, but is on its way.
          In the meantime we've put together a sample integration with SGWTEE for evaluation purposes - check out this forum post:
          http://forums.smartclient.com/showthread.php?t=10593

          Comment


            #6
            What you need here is really good locking strategy. But not on record level but on domain object level. We have tried one approach like in msatkevich post with activity table. We have decide which objects to lock when users starts to edit data related to this objects (which means editing,adding, removing data not only in one table but tables related in 1:n and others kind of relationships). When user starts to edit some object, lock is made and anyone can only view this data. But this approach has one disadvantage: when user didn't finish his work properly the lock on record remains. This force our client to run special administration service to unlock records for another users.
            Another approach is with activity table stored as bean in container memory (with periodical session expiration checking). When system crashes all records become unlocked, when user exits application during editing, session expiration checking couse to unlock record (but what about several container instances ?). This approach was not tested for big volume of users
            The main question here is how exact my data has to be for me to decide whether I can take next action.

            Comment


              #7
              We used the gwt-comet (http://code.google.com/p/gwt-comet/) implementation to notify other users (server-push) when an object is updated and other clients need to be informed about ! Dependant on the updated object the client then "invalidated" the datasource - to reload the information.
              The solution is very stable and also provides a hearbeat - so you always know how many users are connected!

              Comment


                #8
                Originally posted by Isomorphic
                The following may be of interest to people watching this thread:

                The Messaging module has still not been officially ported to SmartGwt EE, but is on its way.
                In the meantime we've put together a sample integration with SGWTEE for evaluation purposes - check out this forum post:
                http://forums.smartclient.com/showthread.php?t=10593
                Sounds good.

                However, as far as I can tell from the docs, this feature will only cover getting the messages to the client, and does not involve things like automatically integrating data changes into the local caches, etc.

                Is there something like this planned, or should we just invalidate caches and re-fetch everything on every change?

                Comment


                  #9
                  See the DataSource.updateCaches() API.

                  Comment


                    #10
                    messaging module vs. Google App Engine

                    According the Messaging Quick Reference (referenced here: http://forums.smartclient.com/showthread.php?t=10593), this system works without polling, so I assume that there are some connections which are kept open.

                    However, according to http://code.google.com/intl/hu/appen...html#Responses, Google App Engine does not supports "streaming data" (ie. sending some data to the client, waiting, then sending more data. )

                    Does this mean the the messaging module (in it's current form) is incompatible with Google App Ending?

                    (Of course, this whole question only makes sense if the core ISC java server can be run under Google App Engine.

                    For the bigger picture, see my other question here:http://forums.smartclient.com/showthread.php?t=11079)

                    Comment


                      #11
                      The wording on Google's base isn't perfectly clear, but most likely it is not yet supported by GAE. We have not run tests for this particular module. The core server is compatible with GAE, up to an including custom DataSources, but of course, not the Hibernate or SQL engines. A JPA-based GAE-compatible DataSource is planned (no ETA).

                      Comment


                        #12
                        OK, so for messaging on GAE, I will use some custom polling solution. For other, GAE-related questions, let's continue this on the other thread.

                        Comment


                          #13
                          This page provides a mechanism for handling concurrent users with minimal overhead but does not deal with the stale data issue:
                          https://isomorphic.atlassian.net/wik...g+transactions

                          Comment

                          Working...
                          X