Send User a Message that he has you locked from a record

Earlt

New Member
I would like to use the <user> from the following error message to send the user a message that he has the system locked from a particular file. Is there a way to do it?

I am using Progress version 9.1D and use very little GUI in my programs.




<file-name> in use by <user> on <tty>. Wait or choose CANCEL to stop. (2624)

You tried to access a data record that is locked by another user. The message tells you the table the record is in and the user who has locked the record. Either choose CANCEL to terminate your operation, or wait for the other user to release the locked record.


Earl T
Application Programmer
Metal-Fab, Inc.
 

joey.jeremiah

ProgressTalk Moderator
Staff member
off the top of my head i can't think of a simple trigger you can add to do just that.

you can, do a find no-wait and check if the record is locked.

Code:
find item where item.itemnum = 1 exclusive-lock no-wait no-error.

if locked item then sendmail( "get out now !" ).
you can use smtpmail.p or outlook to send emails, theres lots of examples @peg.com, or checkout scott auge's 4gl wiki.


you can also use optimistic locking, meaning, the record is not locked while the user is updating.

the record is read with no-lock.

before commiting changes the records is checked if any changes were made after it was read, to ensure isolation (transaction acid properties).

and finally the record is locked only to commit the changes.


optimistic locking is a common practice with stateless arch where the client and appserver operate mostly separate from each other and obtaining locks may not be possible.

you'll also get rid of the user gone to lunch effect (or weekend, in some cases) :)
 

calv83

New Member
[FONT=&quot]Hi All,

Sorry for bringing up this topic again, but is there any other ways without having to use the smptmail.p or even send an email. i.e. Send a Message Alert-Box to their desktop instead?

Reason to not use the email is because some developers who I work with never reads their email, so rather than sending out an email, I want to send out a pop up message box.

I've written a script which uses the net send and it does the following:

- Assumptions -
> You are connected to the database where you want to apply schema changes, or updates to the database.

1) The script goes through Progress's _connect table; this table gives out the user name and the machine which they are logged onto. They are then stored in a temp-table.

2) It will then stream out and create a .bat file.

3) Now it will loop through the temp-table and create the first command, which is to start up the Messenger service. (If this service is not started, net send will not work).

4) Now it will loop through the temp-table again and create the second command, which is to use net send with the message 'Please log out...'.

NB: Reason why I need to loop through it twice is because, if I use the command to start the service and run the net send, I will get an error as it takes some time for net send to start up.

5) Once the batch file is completed the script will ask if you want to run the batch now or another time.

I've tested it out and it works fine. BUT... there's two issues:
1) You don't always have permission to start the Messenger service on all user machines, unless you are the admin.

2) If the user was logged onto a remote desktop machine and there are 5 users, all 5 users will be using the same host, therefore you don't always know who is actually connected to the database.

Any ideas to overcome these issues?

Thanks in advance.
Calv

PS: Here's the code:

DEFINE STREAM gvsOutput.

DEFINE VARIABLE gvcMachineName AS CHARACTER NO-UNDO INITIAL "CLUC02".
DEFINE VARIABLE gvcCommandLine AS CHARACTER NO-UNDO.
DEFINE VARIABLE gvcOutputFile AS CHARACTER NO-UNDO INITIAL "C:\Temp\StartServices.bat".
DEFINE VARIABLE gvlSendMsgNow AS LOGICAL NO-UNDO.

DEFINE TEMP-TABLE ttUserMachine NO-UNDO
FIELD ttUser AS INTEGER
FIELD ttMachine AS CHARACTER
INDEX ttIdx0 IS PRIMARY ttUser.

/* Build Table */
EMPTY TEMP-TABLE ttUserMachine.
FOR EACH _connect WHERE _connect._Connect-PID <> ?
AND _connect._Connect-Type = "REMC"
NO-LOCK:
FIND FIRST ttUserMachine WHERE ttUserMachine.ttMachine = _connect._Connect-Device NO-LOCK NO-ERROR.
IF NOT AVAILABLE ttUserMachine THEN DO:
CREATE ttUserMachine.
ASSIGN
ttUserMachine.ttUser = _connect._Connect-PID
ttUserMachine.ttMachine = _connect._Connect-Device.
END.
END.

/* Exit Code if there are no user's logged on to the databas */
FIND FIRST ttUserMachine NO-LOCK NO-ERROR.
IF NOT AVAILABLE ttUserMachine THEN RETURN.

/* Write batch script */
ASSIGN gvcOutputFile = "C:\Temp\StartSendStopToAll.bat".
OUTPUT STREAM gvsOutput TO VALUE(gvcOutputFile).

FOR EACH ttUserMachine NO-LOCK:
ASSIGN gvcCommandLine = "sc \\" + TRIM(ttUserMachine.ttMachine) + " start messenger".
PUT STREAM gvsOutput gvcCommandLine FORMAT "x(100)" AT 1.
END.

FOR EACH ttUserMachine NO-LOCK:
ASSIGN gvcCommandLine = "net send " + TRIM(ttUserMachine.ttMachine) + " ~"Please log out of Garradin!~"".
PUT STREAM gvsOutput gvcCommandLine FORMAT "x(100)" AT 1.
END.

OUTPUT STREAM gvsOutput CLOSE.

MESSAGE "Do you want to run the batch file now?" VIEW-AS ALERT-BOX INFORMATION BUTTONS YES-NO UPDATE gvlSendMsgNow.
IF gvlSendMsgNow = NO THEN RETURN.
ELSE DO:
IF SEARCH(gvcOutputFile) <> ? THEN DO:
OS-COMMAND SILENT VALUE(gvcOutputFile).
END.
END.

MESSAGE "Do you want to delete the batch file now?" VIEW-AS ALERT-BOX INFORMATION BUTTONS YES-NO UPDATE gvlSendMsgNow.
/* Once the message had been sent, delete the batch file */
IF gvlSendMsgNow = NO THEN RETURN.
ELSE DO:
IF SEARCH(gvcOutputFile) <> ? THEN DO:
OS-COMMAND SILENT ATTRIB -R VALUE(gvcOutputFile).
OS-DELETE VALUE(gvcOutputFile).
END.
END.


[/FONT]
 

GregTomkins

Active Member
Sounds like a ton of work for something that (a) is basically merely enhancing a pre-existing error message and (b) should hardly ever happen.

We have a push-based messaging infrastructure based on Sonic (it is pushing to PSC WebClients), it works well but we put a ton of work into it as well as $$ in the form of Sonic licences.
 

Cringer

ProgressTalk.com Moderator
Staff member
We have set up a basic socket listener in our application. You can then send a message via the socket which would then pop up a message to the user. In fact we have implemented a way for the admin to send all logged in users a message to say log out as the db will be restarted soon for example. It's not the most robust solution though. But it might be worth investigation.

I can't post details of our solution here though as that would be in breech of my contract... :D
 
Top