Why does Progress go back to the initial screen after a session crash? - openedge

Hello all and thanks for viewing this question,
I have a program that users get access to via a login screen. Once the user's credentials have been validated on the login screen, the main program is called (from the login screen) and the login screen disappears. All good. However, if the session crashes (or I press CTRL-PAUSE), the main program is terminated and I end up at the initial login screen. I'd have assumed that after a session crash, Progress (11.4) should take me back to the OS (Windows Server 2012), but not back to the initial screen. I have tried placing QUIT in different areas of the program, but Progress still takes me back to the initial screen, while I need it to quit completely. Any thoughts would be greatly appreciated. Thanks!

It's the AVM's default behavior to rerun the startup procedure after a STOP condition has occurred that was not handled.
You can add an
ON STOP UNDO, RETURN "stopped" .
option to a DO, FOR or REPEAT block close where your "crash" happens. Then the calling procedure could check for the RETURN-VALUE of "stopped".
Assuming you are on a recent version (OpenEdge 12.x), you can also use CATCH Blocks for Progress.Lang.Stop:
CATCH stopcon AS Progress.Lang.Stop:
QUIT.
END CATCH.

I think that your use of the word "crashed" is very, very confusing. If your session actually "crashes" in the usual sense that _progres (or prowin if this is Windows) terminates, then you would not have any locked records remaining. You would also have a protrace file that would help you to identify where the issue occurs.
Incidentally, you could add error logging to the client startup to determine where the errors that QXtend cannot find are occurring:
_progres dbname -p startup.p -clientlog logname.log
You have not shared any code so I can only guess but, presumably, you are running your login program via the -p startup parameter.
Correct me if I am wrong but something along these lines:
_progres dbname -p startup.p
The startup program then runs whatever it runs to get you logged in and run the application. Maybe something like this:
/* startup.p
*/
message "(re)starting!".
pause.
run value( "login.p" ).
run value( "stuff.p" ).
message "all done".
pause.
quit.
And:
/* login.p
*/
message "hello, logging in!".
pause.
return.
Along with:
/* stuff.p
*/
message "hello, doing stuff!".
pause.
run value( "notthere.p" ).
message "hello, doing more stuff!".
pause.
return.
At some point an error occurs (you seem to want to call this a "crash"). I have arranged for a serious error to occur when stuff.p tries to "run notthere.p". So if you run my example you will see the behavior that you have described - your session "crashes", the startup procedure re-runs, and you get to the login screen again.
To change that and trap the error simply wrap a "DO ON STOP" around the RUN statements. Like this:
/* startup.p
*/
message "(re)starting!".
pause.
do on error undo, leave
on endkey undo, leave
on stop undo, leave
on quit undo, leave: /* "leave", exits this block when one of the named conditions arises */
run value( "login.p" ).
run value( "stuff.p" ).
/* we just leave because we finished normally */
end.
message "all done".
pause.
quit.
You mention QXtend so I am guessing that MFG/Pro is involved. If you cannot directly modify the MFG/Pro startup procedure (as I recall that would be "-p mfg.p") just adapt the code above to be a "shim" that runs mfg.p from within the "DO ON STOP..." block.

I believe I have found a way to quit the initial login screen when this appears as the result of a session crash, by using the the ETIME function. Thanks again, Mike for your response.

Related

Kernel cancelling a `input_request` at the end of the execution of a cell

I'm implementing a new Go kernel, using directly the ZMQ messages. But as an extra I want it to execute any bash command when a line is prefixed with !, similar to the usual ipython kernel.
One of the tricky parts seems to be bash scripts that take input -- there is no way (that I know of) to predict when I need to request input. So I took the following approach:
Whenever I execute a bash script, if it hasn't ended after 500ms (configurable), it issues an input_request.
If the kernel receives any input back (input_reply message), it writes the contents to the bash program's piped stdin (concurrently, not to block), and immediately issues another input_request.
Now at the end of the execution of the bash program, there is always the last input_request pending, and the corresponding widget expecting input from the user.
Jupyter doesn't drop the input_request after the execution of the cell ended, and requires the user to type enter and send an input_reply before another cell can be executed. It complains with "Cell not executed due to pending input"
Is there a way to cancel the input_request (the pending input) if the execution of the last cell already finished ?
Maybe there is some undocumented message that can be send once the bash program ends ?
Any other suggested approach ?
I know something similar works in colab.research.google.com, if I do:
!while read ii; do if [[ "${ii}" == "done" ]] ; then exit 0; fi ; echo "Input: $ii"; done
It correctly asks for inputs, and closes the last one.
But I'm not sure how that is achieved.
Jupyter's ipython notebook doesn't seem to have that smarts though, at least here the line above just locks. I suppose it never sends a input_request message.
many thanks in advance!

Strange ZQuery behavior

I'm using Zeos and SQLite3 DB in Delphi
ZQuery2.Close;
ZQuery2.SQL.Clear;
ZQuery2.SQL.Add('SELECT * FROM users WHERE un = ' + QuotedStr( UserName ) );
ZQuery2.Open;
OutputDebugString(PWideChar( ZQuery2.FieldDefList.CommaText )); // log : id,un,pw
OutputDebugString(PWideChar(ZQuery2.FieldByName('pw').AsString)); //causes error sometimes
the code is working but sometimes I get the following error message
Exception class EDatabaseError with message 'ZQuery2:Field'pw' not found'.
This is odd because a field of a dataset shouldn't just disappear while the app is in the middle of running, especially if other fields are still operating normally. So, I would suspect something like a memory overwrite being the cause.
Memory overwrites usually happen when something is written to the wrong place in memory, overwriting what is there, usually because of an incorrect pointer value or a so-called "buffer overrun" where the writing operation carries on beyond where is should stop. Usually, the pointer value is so wildly wrong that the OS can detect it and raise an AV, but sometimes it is less obvious.
Delphi's memory manager has a 'full debug mode' which adds special checks for this condition, see here.
I suggest you enable full debug mode as per the linked document and wait for the exception to occur.

NetLogo: Can't "stop" forever button from another procedure?

I have simplified my problem below. I want to stop the execution of the forever button "go" when there's no robots, and I want to call this from another procedure ("test" in this case) like so:
to go
test
end
to test
if not any? robots [ stop ]
end
The reason for this is that I want to call stop where the robot dies such that I can send an appropriate user message.
Sadly, you must re-organize your code so that the you call if not any? robots [ stop ] in your go in order for the following to be true:
See the documentation:
A forever button can also be stopped from code. If the forever button
directly calls a procedure, then when that procedure stops, the button
stops. (In a turtle or patch forever button, the button won’t stop
until every turtle or patch stops – a single turtle or patch doesn’t
have the power to stop the whole button.)
Ref:http://ccl.northwestern.edu/netlogo/docs/programming.html#buttons
stop This agent exits immediately from the enclosing procedure, ask,
or ask-like construct (e.g. crt, hatch, sprout). Only the enclosing
procedure or construct stops, not all execution for the agent.
Ref: http://ccl.northwestern.edu/netlogo/docs/dict/stop.html
One alternative hacky solution which I'm tempted to not post may be to do the following where you raise an error in which then stops.
to go
carefully[test][error-message stop]
end
to test
if not any? robots [ error "no more robots!" ]
end

STM32F7 hangs after system reset

I have the following problem:
STM32F7 Flash starts at 0x0800 0000. My program works fine.
Then I shift my code in FLASH at 0x0802 0000 to leave space for future bootloader. I changed my MemoryMap.xml file :
<MemorySegment start="0x08020000" name="FLASH" size="0x80000" access="ReadOnly"/>
and the corresponding flashplacement.xml file:
<ProgramSection alignment="0x100" load="Yes" name=".vectors" start=" 0x8020000"/>
and start debuging....Program works fine until an link error occurs which triggers a system restart with a call of HAL_NVIC_SystemReset.
The result is a hanging application which is not the case when my code resides at the start of FLASH (0x0800 0000)
Does anybody knows why is this happens?
Regards
/Kostas
The answer is rather easy. You cant just move memory start address. Your micro will get the stack pointer value and the reset handler routine address from the same address as usually. You need to have this boot loader already flashed( at least the vector table and the reset handler which will set the new vector table, set the app stack pointer and pass the control to your app reset handlet

Window not activating/appearing in front

I have a script that opens a webpage, logs in, then opens a program and is supposed to bring the program to the front and make it full screen. It opens the window but it does not always bring it to the front and it won't full screen. Can anyone offer any assistance? Here is my code:
; Closes last dialog if still open
Sleep(5000)
Send("{ENTER}")
Sleep(500)
; Wait for program to open
WinWait("[CLASS: Program example]","", 5)
;Brings Program to front
if WinExists("[CLASS: Program example]") Then
WinActivate("[CLASS: Program example]")
EndIf
Sleep(500)
; Sets program fullscreen
WinSetState("[ACTIVE]", "", #SW_MAXIMIZE)
I added the WinWait to see if that would help, but it has not. The window just stays in the back and never moves. Thanks for any help provided.
Sometimes AutoIt doesn't perform some task because something is happening at the same time that interfere with the command. The best way to ensure the things work is to always check if the task was performed and try again if not. This loop will solve your problem.
;Brings Program to front
While Not WinActive("[CLASS: Program example]")
WinActivate("[CLASS: Program example]")
Sleep(1000) ; Wait one second (or any seconds you want)
WEnd

Resources