Print Page | Close Window

[ANSWERED] Multi-User Behavior

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce Classic
Forum Discription: For .NET 2.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=519
Printed Date: 09-Dec-2019 at 5:08am


Topic: [ANSWERED] Multi-User Behavior
Posted By: Linguinut
Subject: [ANSWERED] Multi-User Behavior
Date Posted: 23-Oct-2007 at 3:44pm
Tomorrow, I am demonstrating the application that I have built so far based on the Cabana model.  In that demo, I am going to make a statement in response to one of the execs.  I will be asked, "If one user adds a new widget, will that widget show up in another users widget list?"  And my response will be..."Absolutely!"  What I really mean is, "I absolutely hope so!"  Can someone confirm that this behavior will in fact happen in a multi-use environment?
 
Thanks,
Bill



Replies:
Posted By: Bill Jensen
Date Posted: 23-Oct-2007 at 5:52pm
Could you clarify what you mean by "widget" and "another user's widget list".
 
Bill J.


Posted By: Linguinut
Date Posted: 23-Oct-2007 at 5:54pm
Sure.  I am an engineer and responsible for entering machine information.  A fellow employee is a technician and creates work orders.  He assigns a machine from a drop down list to a work order.  If I add a new machine, will the new machine show up in his drop down list?


Posted By: davidklitzke
Date Posted: 24-Oct-2007 at 7:59am
This is not a Cabana question.  This is a DevForce question.
 
The answer is, "It depends".
 
If you code your application the same way as is done in many of the tutorials (e.g., "Adding and Deleting Business Objects" or "Working with ComboBoxes"),  your new machine will not show up in your fellow technician's dropdown list.  However, if your fellow technician adds a ListManager to the EntityList in his dropdown list to filter all existing machines, the machine you just added will show up automatically in his dropdown list.


Posted By: Linguinut
Date Posted: 24-Oct-2007 at 9:56am
This is a CAB question, since much of the mechanics of manipulating entities is handled in a workitem with services, resources and such.  As much as I possibly can, I am utilizing CAB structure and functionality.  I am doing my best to write the app in a CAB way (using ListConverterService, etc.).  It is rather rare to have to directly create a binding source in a view, for example (don't recall doing it, yet).  With that in mind, I would like to know if there are gotchas that come with DF/CAB in a multi-user environment.  In other words, if I code the Cabana way, do I need to do something differently to manage a multi-user environment.  My gut says "no", that I don't need to do anything additional, but I would like some assurance here.  That's all.  So, should I hang my hat on the "it depends" response?  It would be kind of like my prepared response to the execs--"I absolutely hope so."
 
By the way, most of the tutorials are obviously not designed with CAB in mind.  As a matter of fact, in most cases, I cannot follow a tutorial and still consider my code CAB-worthy.


Posted By: Bill Jensen
Date Posted: 24-Oct-2007 at 12:13pm

Some additional comments:

Building robust multi-user applications is non-trivial and requires careful application-specific design--there is no "out of the box" solution.
 
CAB (or rather the Cabana wizards) may have created the binding sources for you, but your code supplied their data sources (typically by querying data from a persistence manager).  Keeping that data up to date is a raw DevForce task.
 
DevForce's managed lists synchronize EntityLists with changes in the cache of the related PersistenceManager in the executing client.  As you've found, if coded properly with managed lists, drop-downs will stay in sync with their PM's cache.
 
The Cabana EntityManager class maintains local (client-side) synchronization between multiple PMs in the same executing client.
 
Synchronizing data in PMs of two client instances (that may be on opposite sides of the world) occurs by arranging to re-query the data.  DevForce provides some tools, but it's up to you to decide how they should be used in your application.
 
(DevForce does offer "push" technology, but it's complex and they tell me it's really "pull" under the hood.)
 
Obviously, synchronization occurs when the client is stopped and restarted.
 
Other options include,
 
Add a refresh button of some kind to force re-query.
 
Have your application periodically requery critical data.
 
Arrange to refresh (requery) when a particular page is displayed or some other UI event occurs.
 
Also keep in mind that, beyond synchronization, multi-user applications must deal with concurrency conflicts--handling the case where two clients have changed the same entity and then each tries to save.   Does the second save overwrite the first save's changes?  Is an error thrown?
 
Again, DevForce provides some tools and guidance (there's a good tutorial on the subject), but you must provide application specific implementation.
 
So I guess a possible answer to your exec's question is "It will once we complete the design and implementation of the application".
 
Bill J.


Posted By: Linguinut
Date Posted: 24-Oct-2007 at 12:19pm
Thanks a ton, Bill.  I appreciate the clarity. 
 
What if a Business Object Server is used?
 
(demo countdown: 40 minutes)


Posted By: Bill Jensen
Date Posted: 24-Oct-2007 at 1:20pm
No real change.  The BOS does not maintain server-side entity state.
 
B.


Posted By: Linguinut
Date Posted: 24-Oct-2007 at 6:02pm
Ok.  Major work ahead.  This does change my thinking and approach to my development.  Thanks.  I appreciate the input!


Posted By: Linguinut
Date Posted: 31-Oct-2007 at 11:04am
Any tech tips or whitepapers on this topic?


Posted By: davidklitzke
Date Posted: 31-Oct-2007 at 2:15pm

To keep data on a client synchronized with the  data on the database, you can periodically query the database.  This is typically done through the use of Asynch Queries.  For more info on Asynch Queries, see the Developer's Guide or the Advanced "Asynchronous Queries" tutorial ("Run on background threads and fire an event when complete. Learn how to use them to keep client-side performance crisp and/or keep local data at any desired level of currency.")

Another strategy is to use "Push" technology to register your interest in certain parts of the database using a "Publisher - Subscriber" model. With "Push" technology, there is the possibility of getting very quick response to very recent changes in the database.  On the other hand, it may be more important to get good performance of the application by not querying the database too frequently using Asynchronous Queries.  In many cases, the best solution is one which balances the need to get the most recent changes in the database with the need to have the best application performance,  If you want to learn more about Push, I suggest looking at the Advanced tutorial on "Push Notifications - Business Object Server to Clients ("Push, or the Notification Service, allows your client applications to "subscribe" to logic/events on the BOS. You determine the server code to be run as part of the service, the client code to be called, the frequency of notification, which clients are notified, and what the notification message contains. Note that this feature is available only when using WCF for distributed communications with the BOS.")



Posted By: davidklitzke
Date Posted: 31-Oct-2007 at 2:21pm
Here is a white paper overview of the "Push" Technology:
 

What is DevForce's Push Feature?

Some of our customers want the central server to "push" information to registered clients when a particular something happens. 

Note that this communication occurs when the server thinks it should happen, not in response to any particular request from a client.

"Push" technology is what makes this work.

 The Polling Alternative

We recommend async query to our customers who want to learn when something of interest has happened. For example, the client can issue an async query to learn if there have been any changes to the list of currently available theater seats. Every few seconds, the client asks the database "Any changes to the theater seats?". The database responds "No" most of the time but occasionally responds with a collection of theater seats that have been changed (e.g., reserved).

This is called "polling". 

What's Wrong with Polling?

We think it is just fine in 99% of cases. 

Recently, a number of prospects have been insistent that polling is bad - or at least bad for their applications.

The perceived problem with polling is that a great many clients could be checking in over and over, clogging the network and diminishing server performance. It's a bit like having a thousand kids in the back seat screaming "are we there yet?". 

Servers, unlike human parents, do not get tired or irritated. They do have to respond to each request, as often as it arrives. The fear is that if a great many clients clamor for information and if there is limited bandwidth to carry the traffic in requests and responses, the network and / or server performance will deteriorate.

With "Push", clients register just once that they want to know when "this" (whatever "this" is) happens: "tell me when we get to grandma's house".

The BOS will be able to host a "daemon" process that (a) clients register to and (b) that calls back into the client when "this" happens: "hey, kids, we've arrived; say Hi to grandma". The client either finds all the information needed inside the call-back from the daemon or knows to go get what it wants: "Hi grandma; where are the presents?".

This feature makes sense only with the BOS 

Although one could write a daemon that runs on the client in 2-tier, it won't be achieving its purpose of reducing the chatter of a "polling" strategy. That's because the daemon itself typically polls*. That's fine when the daemon runs on the host server; it translates to client-side polling when the daemon runs on the client.

* It is theoretically possible to install MSMQ (Microsoft's messaging technology which provides push technology) on each client and design the daemon to use it. The daemon would not have to poll. However, this approach is only viable if the client is already running MSMQ for some other reason - it's a pretty tricky install just for a DevForce client app.

This is why I described the BOS as providing "meaningful" push. You could do it 2-tier but you'd probably just be moving the polling out of your main thread and into another; you haven't really addressed the screaming child problem.

 



Posted By: Linguinut
Date Posted: 01-Nov-2007 at 10:09am
So, stick to async querys (polling) in 2-tier implementations and utilize the push feature when involving a BOS...right?
 
I think I understand the gist of either procedure.  The trouble comes in with the vast amount of code to create for this.  I realize that not everything needs this kind of data synchronization; however, it will get messy.  Also, where do these things happen within DF/CAB?  To keep things separated from the view, I suspect it would be best to implement the polling from the presenter.  Or, is there an even better place to do this...controller?  workitem?  rootworkitem?  Should I somehow consider a service mechanism to make this happen?
 
In addition, are SQL Server 2005 Notification Services the only thing that could drive the push mechanism?  I do not have SS2K5, nor do I expect to upgrade to it (2008 is getting close).  How am I limited without that database management system?
 
Thanks,
Bill



Print Page | Close Window