Thread: [PyPerSyst-Devel] concurrent users
Brought to you by:
pobrien
From: Donnal W. <don...@ya...> - 2003-10-24 11:44:24
|
Could someone please remind me how one would set up a database with PyPerSyst for multiple concurrent users? Is anyone using PyPerSyst this way right now? This subject is only periperally related to the thought experiment on which I am presently working (which is going well, BTW), but I don't want to do anything that would make it more difficult to implement a system for current users in the future. Regards, ===== Donnal Walter Arkansas Children's Hospital |
From: <po...@or...> - 2003-10-24 15:53:00
|
Donnal Walter <don...@ya...> writes: > Could someone please remind me how one would set up a database with > PyPerSyst for multiple concurrent users? Is anyone using PyPerSyst > this way right now? This subject is only periperally related to the > thought experiment on which I am presently working (which is going > well, BTW), but I don't want to do anything that would make it more > difficult to implement a system for current users in the future. The applications I have developed with PyPerSyst have multiple clients, both command line (daemon programs, actually) and web browser clients. I haven't done any gui clients yet, but the same principles apply. PyPerSyst does not provide all the tools you need to create an application that supports multiple concurrent users. A complete solution will need to include either Pyro or Twisted. PyPerSyst does include some helper modules that make it easier to create Pyro or Twisted applications. At this point it is easier to leverage Pyro and Twisted, than it is to create similar functionality in PyPerSyst itself. I especially like using Twisted with PyPerSyst. Basically, what you do is create a server application using either Pyro or Twisted. Then you create one or more client applications. These clients could be command line, web, or gui. The server and client apps could be run on the same machine, or on separate machines. It is pretty easy to modify an existing database schema so that it can work with either Pyro or Twisted. So there really isn't too much that you have to do in this regard. About the only thing you have to think about is how you want to handle insert/update/delete conflicts. For example, if an update transaction object was created based on values for an instance that was subsequently changed by another user, should this update transaction still take place? In other words, you might have the following sequence of events: 1. Client A gets values for object X and creates an update transaction. 2. Client B gets values for object X and creates an update transaction. 3. Client B sends their transaction to the server to be executed. 4. The transaction is executed and object X is updated. 5. Client A sends their transaction to the server to be executed. 6. Should object X be updated? Or should the transaction be rejected? In the entity package a revision attribute is assigned to all Entity instances and is incremented each time they are updated. Transactions can use this attribute to help determine whether a transaction should take place or not. The Extent class enforces the revision check if a revision number is supplied. For example, here is the extent._update() method: def _update(self, instance, rev=None, **attrs): """Update the instance, then return it.""" instance = self.get(instance, instance) if rev is not None and instance.rev != rev: msg = '%r is rev %s, not rev %s' % (instance, instance.rev, rev) raise error.UpdateRevisionMismatch, msg combined = instance._attrs() combined.update(attrs) self._validate(instance, combined) self._removelinks(instance) self._removekeys(instance) instance._update(attrs) self._addlinks(instance) self._addkeys(instance) return instance How this UpdateRevisionMismatch exception should be handled by the user interface is up to the client application. In some cases the changes should simply be dropped. In other cases, the user may have spent a lot of time typing in the changes and would lose a lot of work if you didn't give them the option to resolve any anomolies and create a new transaction. A lot depends on the particular domain. The issues are basically the same as with any multi-user database. I'm open to any suggestions if there are other mechanisms that would be useful to have support for in PyPerSyst. Did that help answer your questions? -- Patrick K. O'Brien Orbtech http://www.orbtech.com/web/pobrien ----------------------------------------------- "Your source for Python programming expertise." ----------------------------------------------- |
From: Donnal W. <don...@ya...> - 2003-10-28 11:26:17
|
--- "Patrick K. O'Brien" <po...@or...> wrote: > How this UpdateRevisionMismatch exception should be handled > by the user interface is up to the client application. In > some cases the changes should simply be dropped. In other > cases, the user may have spent a lot of time typing in the > changes and would lose a lot of work if you didn't give them > the option to resolve any anomalies and create a new > transaction. A lot depends on the particular domain. The > issues are basically the same as with any multi-user database. > I'm open to any suggestions if there are other mechanisms > that would be useful to have support for in PyPerSyst. > Did that help answer your questions? Yes it did, thanks. I realized later, however, that my subject line is somewhat misleading. The apps I hope to develop are *multi-user* in a sense, but probably not truly *concurrent* users. If you will indulge me, let me try to describe the situation. The domain I have in mind is clinical, and multiple clinicians will need to update the patient information. But for any given patient at any given time, *only one* clinician will typically need to update the information. It would work well for a clinician to be able to check out a patient record, and until that record is checked back in, other users could *see* the record but would not be allowed to modify it. This is not an artificial scenario made up to over simplify the problem. It is the typical situation. In the case where two clinicians want to update information at the same time, the second could simply be informed (before the fact) that the record is checked out temporarily. It might seem like Twisted would be a good solution here, since there would be relatively few update conflicts, but IMHO it would be better to inform a user that a given record is in use *before* editing the data rather than during an attempted transaction. PyPerSyst, if I understand correctly, keeps the entire database in memory, but I don't see why there couldn't be multiple "documents" in place of a single "root". Each document would have a "snapshot" and possibly a "log file". Any valid user should be allowed to open a snapshot for reading at any time. But if the user wants to check out a document for updating, the application should first check to see if there is a "log file" for that document. If so, it assumes that another user is updating the document and leaves it alone. If not, it creates a log file: (1) for logging transactions, and (2) for letting other users know that they cannot have write access at present. When the editing is finished, a new snapshot is saved and the log file is deleted (letting another user know that it is safe to open it in update mode). Regards, ===== Donnal Walter Arkansas Children's Hospital |
From: <po...@or...> - 2003-10-28 14:07:01
|
Donnal Walter <don...@ya...> writes: > --- "Patrick K. O'Brien" <po...@or...> wrote: > > > Did that help answer your questions? > > Yes it did, thanks. I realized later, however, that my subject line > is somewhat misleading. The apps I hope to develop are *multi-user* > in a sense, but probably not truly *concurrent* users. If you will > indulge me, let me try to describe the situation. > > The domain I have in mind is clinical, and multiple clinicians will > need to update the patient information. But for any given patient > at any given time, *only one* clinician will typically need to > update the information. It would work well for a clinician to be > able to check out a patient record, and until that record is > checked back in, other users could *see* the record but would not > be allowed to modify it. This is not an artificial scenario made up > to over simplify the problem. It is the typical situation. In the > case where two clinicians want to update information at the same > time, the second could simply be informed (before the fact) that > the record is checked out temporarily. I understand. Other domains have a similar need to regulate access to information according to who is the responsible party for updates. > It might seem like Twisted would be a good solution here, since > there would be relatively few update conflicts, but IMHO it would > be better to inform a user that a given record is in use *before* > editing the data rather than during an attempted transaction. That could be handled any number of ways. > PyPerSyst, if I understand correctly, keeps the entire database in > memory, but I don't see why there couldn't be multiple "documents" > in place of a single "root". Each document would have a "snapshot" > and possibly a "log file". Any valid user should be allowed to open > a snapshot for reading at any time. But if the user wants to check > out a document for updating, the application should first check to > see if there is a "log file" for that document. If so, it assumes > that another user is updating the document and leaves it alone. If > not, it creates a log file: (1) for logging transactions, and (2) > for letting other users know that they cannot have write access at > present. When the editing is finished, a new snapshot is saved and > the log file is deleted (letting another user know that it is safe > to open it in update mode). I think it is important to separate the logical requirements from any physical implementation that could support those requirements. Your requirement is to restrict access to an entity. For that you need to know who the user is (name and password, perhaps) and then be able to assign entities to that user. If an entity is already assigned, another user can only have read access to the data, but no update capabilities. How this gets implemented depends on other requirements. In particular I think it needs to be established whether information needs to be shared between any of these patient documents, or whether they are completely independent of each other. If they are as independent as you seem to suggest, then your implementation (separate databases for each) would be one way to handle things. But if there is a need to share information, or look at all patient documents at the same time, your implementation might not be the best. Do you have the need to support any of the following: * List all the clinicians and the patients they have been assigned. * List all the patients and their current clinician. * Tell me which patient was in exam room 3, yesterday at 3:00pm. * List all the patients who were given EKGs last Friday. * Calculate the clinician/patient ratios by week for the past 3 months. * List all the patients treated by Clinician X last week. Please don't laugh if any of those examples is completely ridiculous. I'm not a doctor, I'm only pretending to be one for Halloween. (Doctor Frankenstein, at your service.) -- Patrick K. O'Brien Orbtech http://www.orbtech.com/web/pobrien ----------------------------------------------- "Your source for Python programming expertise." ----------------------------------------------- |
From: Donnal W. <don...@ya...> - 2003-10-28 16:06:19
|
Patrick K. O'Brien: > Donnal Walter: > > The domain I have in mind is clinical, and multiple clinicians > > will need to update the patient information. But for any given > > patient at any given time, *only one* clinician will typically > > need to update the information. ... > > I understand. Other domains have a similar need to regulate > access to information according to who is the responsible party > for updates. Ok, but what I was suggesting is that READ access be regulated for groups of clinicians, but that UPDATE access be controlled by the client application itself, based on the patients that a clinician *assumes* responsibility for (not *assigned*). (See comments below on eliminating the server, as well.) > > PyPerSyst, if I understand correctly, keeps the entire database > > memory, but I don't see why there couldn't be multiple > > "documents" in place of a single "root". Each document would > > have a "snapshot" and possibly a "log file". Any valid user > > should be allowed to open a snapshot for reading at any time. > > But if the user wants to check out a document for updating, the > > application should first check to see if there is a "log file" > > for that document. If so, it assumes that another user is > > updating the document and leaves it alone. If not, it creates > > a log file: (1) for logging transactions, and (2) for letting > > other users know that they cannot have write access at > > present. When the editing is finished, a new snapshot is saved > > and the log file is deleted (letting another user know that it > > is safe to open it in update mode). > > I think it is important to separate the logical requirements > from any physical implementation that could support those > requirements. As a statement of principle I would agree with this. Nevertheless, the physical implementation is of some importance. First, let me state up front that I am not trying to build a complete patient record system. A lot of patient information will be collected, but many of the applications could easily be envisioned as single user. Second, our current system (which isadmittedly inadequate, but for other reasons) is document-based, with clinicians accessing documents on a shared network drive. I was hoping to leverage this type of simplistic shared access, but with a more robust persistence mechanism and much, MUCH more effective custom applications. Part of my goal was to simulate a form of multi-user access WITHOUT needing separate server software. > Your requirement is to restrict access to an entity. For that > you need to know who the user is (name and password, perhaps) > and then be able to assign entities to that user. If an entity > is already assigned, another user can only have read access to > the data, but no update capabilities. How this gets implemented > depends on other requirements. General access to an entity could be restricted via the operating system. What I was suggesting was that UPDATE access be restricted only via the client software, based on whether it detects that the document is already in use or not. The presence or absence of the log file seemed like a convenient flag (for free). :-) > In particular I think it needs to be established whether > information needs to be shared between any of these patient > documents, or whether they are completely independent of each > other. If they are as independent as you seem to suggest, then > your implementation (separate databases for each) would be one > way to handle things. But if there is a need to share > information, or look at all patient documents at the same time, > your implementation might not be the best. All things being equal, I'd prefer to a separate server to control access to various components of the record system. For purposes of proving a concept, however, I only have available a shared network drive. (I'm not sure that I would be allowed to install executable software such as Twisted, for example.) I'm sure what I suggested above is limited both in its power and its flexibility, but if it allows me to demonstrate the superiority of custom applications built with Python, that may be the best I can hope for at present. > Do you have the need to support any of the following: > > <snip> > > Please don't laugh if any of those examples is completely > ridiculous. I'm not a doctor, I'm only pretending to be one > for Halloween. (Doctor Frankenstein, at your service.) No, I am not laughing, although we don't have need for the kinds of things you mentioned. For the most part these patient documents *really are* that independent. There actually is not a need for sharing information between documents. This is not to say that we would never want to prepare certain summary reports that draw from a large number of documents, but I have always viewed these as being doable in batch mode. Incidentally, the need for ad hoc queries is the best argument I can think of for "relational-like" entities. Ad hoc queries are one the classic problems for object-oriented databases, and setting things up to be more relationally oriented could be a benefit. On the other hand, my applications don't need real-time query capabability other than what is provided by the application itself. Aggregated reports can be done in a non-interactive (batch) mode. Regards ===== Donnal Walter Arkansas Children's Hospital |