Four Js Development Tools Forum

Discussions by product => Genero BDL => Topic started by: Stephen T. on October 15, 2013, 08:14:29 am



Title: Configuring sigint
Post by: Stephen T. on October 15, 2013, 08:14:29 am
If DEFER INTERRUPT isn't used, what key will abort the program? The setup is such that ^C is the cancel/interrupt key, but if I run a program without DEFER INTERRUPT, the interrupt appears to be deferred anyway and just int_flag gets set. I want the program to abort - is that possible?


Title: Re: Configuring sigint
Post by: Reuben B. on October 16, 2013, 10:16:06 pm
Stephen, 

You probably need to provide more context.  Are you running in TUI mode (FGLGUI=0), or do you have a graphical front-end.  If with a graphical client, where are you attempting to send the interrupt from, the server or the client.

This has a little note on the difference running in a graphical front-end https://4js.com/online_documentation/fjs-fgl-manual-html/User/Programs.html#SIGNAL_HANDLING

If with the GDC, you can always abort the program via this tab
https://4js.com/online_documentation/fjs-gdc-manual-html/User/Connections.html

Hope that helps,

Reuben
 


Title: Re: Configuring sigint
Post by: Stephen T. on October 17, 2013, 08:46:05 am
Reuben,
Apologies, the background is this is a migration from BDS to Genero 2.4 running in 'Traditional' gui mode. In the BDS code, I hadn't realised that they didn't use DEFER INTERRUPT, so the ^C simply terminates the program un (dis) gracefully. The same code in Genero doesn't work the same way and the ^C (set as the cancel and interrupt in the 4ad) simply seems to set the int_flag (so the DEFER INTERRUPT seems to be the default?) - so if the program opens with a prompt, you can't get out of the code and even on 'cancel' the code falls through (as ^C isn't then looked for). I had read the manual pages - honest!

Again, I can get around the issue by adding DEFER to the code and then detecting int_flag in the code and then shutting down gracefully (as I'm used to) - but again, I was hoping that I'd missed a setting somewhere and that there was a way of getting the same 'interrupt' functionality in Genero.


Title: Re: Configuring sigint
Post by: Reuben B. on October 18, 2013, 01:01:15 am
Ok, I see the issue.  So take something like ...

Code
  1. MAIN
  2. DEFINE p1,p2,p3 STRING
  3.  
  4.    #DEFER INTERRUPT
  5.    PROMPT "Enter parameter 1? " FOR p1
  6.    PROMPT "Enter parameter 2? " FOR p2
  7.    PROMPT "Enter parameter 3? " FOR p3
  8.    -- CALL generate_report(p1,p2,p3)
  9.  
  10. END MAIN


... in character mode, Control-C at any of the prompts will terminate the program.  In GUI you will get a prompt dialog with an Ok/Cancel button.  Hit Cancel and the program continues on.

In our docs, we say with a GUI client, add an action view for the interrupt action so that the user can trigger the interrupt action.  So if you add a toolbar ...

 --Add a toolbar with accept/cancel/interrupt items
 CALL ui.Interface.loadToolBar("deferinterrupt")

... what you then find is that the interrupt action isn't active, (and even if it was I'd be surprised if it led to the program terminating)

So you could put in an issue to your local support center with an example that more accurately resembles your situation, but I suspect the better long term solution would be to modify the code to use DEFER INTERRUPT and test the int_flag after every dialog statement.  (it is amazing how many CONSTRUCT, DISPLAY ARRAY, PROMPT I come across that don't test the int_flag)

Reuben


Title: Re: Configuring sigint
Post by: Stephen T. on October 18, 2013, 09:13:05 am
Again, thanks Reuben.
As per the PAGE LENGTH 0 issue, this is also part of the same migration. If there's then nothing that I've missed and the Documentation that describes DEFER INTERRUPT '.....DEFER INTERRUPT indicates that the program must continue when it receives an interrupt signal. By default, the program stops when it receives an interrupt signal. ....', is then not quite right, and if there isn't a setting that I've missed to enable this, then the code will have to be addressed as part of the project.

Are you aware of other migration issues that do not appear in the manual? We have hit two or three - do you want me to post them in a BDS 'migration' post? Or do you want to review them and add them to the Docs migration section?



Title: Re: Configuring sigint
Post by: Sebastien F. on October 18, 2013, 09:44:09 am
Stephen,

What is wrong in the doc?

The purpose of DEFER INTERRUPT is to trap the SIGINT signal. Typical 4gl program set this option to avoid program termination when a SIGINT arrives to the the process.

In GUI mode, we have introduced the concept of a special 'interrupt' action, that can be bound to action views (push buttons), to let the front-end send an interruption GUI event to the program while it is executing a long procedure.

Please send individual mails to the support, for each of the issue you faced, including the migration cases.
We will then advice.

Thanks!
Seb


Title: Re: Configuring sigint
Post by: Stephen T. on October 20, 2013, 09:04:03 am
Seb,
Sorry for being thick , but I'm not with you. I thought the doc said that the default is for the program to STOP when the interrupt was received unless you have DEFER INTERRUPT? In the code (as Reuben posted or as below), the INT_FLAG is set, but the program continues.

 MAIN
 DEFINE l_char                      CHAR

    LET INT_FLAG        = FALSE
    DISPLAY 'Mode (',FGL_GETRESOURCE('gui.uiMode'),')'

    WHILE TRUE
        PROMPT 'Int Flag Test ' FOR CHAR INT_FLAG

        DISPLAY 'INT FLAG Is (',INT_FLAG,')'
    END WHILE   

 END MAIN   

What 'key' or interrupt do I use in the above to get  the program to STOP?


As for the migration issues, they do not appear to be bugs in Genero per se, just differences between how/what BDS appears to do and what Genero appears to do.


Title: Re: Configuring sigint
Post by: Reuben B. on October 21, 2013, 06:24:53 am


Quote from: Seb
What is wrong in the doc?

Seb: there is nothing wrong in the doc.  The problem is in the GUI implementation for the rare case when DEFER INTERRUPT is NOT set.  If the developer has followed the instructions in the docs and defined an interrupt action view, they will find that this interrupt action view is not enabled in a MENU or PROMPT statement.  As a result they cannot terminate the program like they can in TUI.

So take something like...

Code
  1. MAIN
  2.   CALL ui.Interface.loadToolbar(<toolbar with interrupt button>)
  3.   OPEN WINDOW w ...
  4.   CALL ui.Interface.Refresh()
  5.   SLEEP 10
  6.   MENU "" -- or PROMPT
  7.      ON ACTION continue
  8.         EXIT MENU
  9.    END MENU

during the SLEEP you will see that the interrupt toolbar item is active and the program can be interrupted.
When the MENU statement arrives, the interrupt toolbar item is no longer active and the user cannot terminate the program like they can in character.  If DEFER INTERRUPT is not set then any user interaction dialog ought to enable the interrupt action.

Stephen: In your code example you haven't followed the instructions in the docs and added an interrupt action view.  Clicking cancel sends the cancel action, not the interrupt action.

Reuben


Title: Re: Configuring sigint
Post by: Stephen T. on October 21, 2013, 08:41:09 am
Reuben,
You're right - there in no action view - mainly as this is a 'conversion' from BDS and the BDS does not have such a view. So what I was after was simply '...is there a way, as in BDS, for a Genero program to terminate whan an interrupt is sent when DEFER INTERRUPT isn't set?....'. The BDS program appears to get the interrupt and abort the program, Genero sets INT_FLAG. I simply thought I'd missed something, that's all. If there is no 'simple' way to get the same behaviour from Genero, then I'm fine with changing the code.

Steve


Title: Re: Configuring sigint
Post by: Sebastien F. on October 21, 2013, 11:01:29 am
Hi,

I think you are confused by the similarity of the "interrupt" special action and the SIGINT interrupt signal handling (DEFER INTERRUPT).

Otherwise you would not ask why the 'interrupt' action view is not active during a dialog.

Let me try to clarify:

By default, when a fglrun process gets a SIGINT signal, it stops. It does not matter where you are in the program. This is the default behavior of C programs on UNIX. On Windows there is no such signal, we use the CTRL_C_EVENT of the SetConsolCtrlHandler() API handle CTRL-C (in console mode only).

The DEFER INTERRUPT instruction is typically used in 4gl to prevent immediate program termination in case of SIGINT signal (or CTRL-C event in a Windows console). You should also consider to use DEFER QUIT, for the SIGQUIT signal.

When you are in TUI mode and you run your program from a console, if DEFER INTERRUPT is not used, on UNIX a CTRL-C will send a SIGINT signal to the program and stop it. No matter if you are in a dialog or not.

When you are in GUI mode, and the program was started from the front-end with a shortcut for ex, the only way to send a SIGINT is to open console, identify the process and use the 'signal' command. It's still good practice to use DEFER INTERRUPT / DEFER QUIT in GUI mode to prevent unexpected program termination.

The 'interrupt' special action is something different: It's designed to be active ONLY when NO dialog is executing. Its purpose is to send an async event to fglrun to set INT_FLAG, to stop a procedure, such as a long running report, or an SQL statement (if the DB allows SQL interruption and OPTIONS SQL INTERRUPT ON was set).

So when a dialog is executing, (can be a MENU or a PROMPT as in your examples), it's normal that the 'interrupt' action view is disabled.

The only purpose of an 'interrupt' button is to set INT_FLAG, outside a dialog context. It will not stop the program. It's in the hands of the programmer to test INT_FLAG in a long running loop:

Code
  1. ...
  2. OPEN WINDOW ... -- open a window/form with progress bar and 'interrupt' button
  3. LET INT_FLAG = FALSE
  4. START REPORT ...
  5. FOREACH c_orders INTO ...
  6.    IF INT_FLAG THEN EXIT FOREACH END IF
  7.    OUTPUT TO REPORT ...
  8. END FOREACH
  9. ...
  10.  

Seb


Title: Re: Configuring sigint
Post by: Stephen T. on October 21, 2013, 11:40:07 am
Seb,
Thanks for the explanation. The problem is that this code isn't being 'designed' - it is code that is there in BDS and being moved to Genero. The code does not (always) use DEFER INTERRUPT in BDS and relies on the ^C from any given interactive dialogue  to terminate the program IMMEDIATELY - ie without recourse to any further program statement. In Genero that isn't the case and with the same code, INT_FLAG is set (when running in normal or traditional mode) and then appears to need a check of INT_FLAG and a program explicit abort. Is that the behaviour that you would expect?
Is there then a 'simple(r)' way to get Genero to behave like BDS?


Title: Re: Configuring sigint
Post by: Sebastien F. on October 21, 2013, 12:02:31 pm
Hello Stephen,

Ok I understand now your request...
But I think you better design your programs to behave as regular GUI applications.
I see no simple way to workaround standard ergonomics with Genero.
Ctrl-C is not the standard key to quit a GUI Window or a program, as you know Ctrl-C is for COPY.
To leave a dialog/window it's Escape (cancel), or something like Alt-F4 (close window).
While I understand that users have the habits of dumb terminals and Ctrl-C, they could make some efforts and learn about GUI keys, if they want to have a GUI interface.
Consider reading the topics about the "close" action:
https://4js.com/online_documentation/fjs-fgl-manual-html/User/InteractionModel.html#XCROSS_CLOSE
The close action can be handled in every dialog. By default it cancels the current dialog.
Maybe you could use it to exit the program.
I think you don't need the 'interrupt' special action in your case.
Seb


Title: Re: Configuring sigint
Post by: Stephen T. on October 21, 2013, 01:22:34 pm
Seb,
The project had already been defined before I joined it and this wasn't defined as an issue. The project was 'simply' to move from BDS to Genero with a few changes - but nothing major on the GUI front in this phase. The old BDS system is using a mixture of 'keys' and tends to use the Informix ESC and ^C for accept and cancel.

I think at this point the simplest thing is to bolt DEFERs into the code where it is lacking and change the code to detect INT_FLAG.

Thanks again.

Steve



Title: Re: Configuring sigint
Post by: Sebastien F. on October 21, 2013, 03:59:33 pm
Stephen,

Some more clarification:

We have checked the code in Genero: in fact when defining a 'interrupt' button in your form, and if you don't use DEFER INTERRUPT, if your are in a long running function / SQL in your program, the interrupt button becomes active, the user can fire the button, and the program stops. This is not documented yet but will be, to clarify the 'interrupt' special action behavior. However, understand that this cannot be used when a dialog is executing (which is 90% of time of an interactive 4gl application), because the 'interrupt' button is disabled during a dialog.

Also: With BDS, the default keys for dialogs were ESCAPE to 'accept' the dialog, and CTRL-C to 'interrupt' ... and when not using DEFER INTERRUPT, the program stopped in any case (inside or outside dialogs)...

So my next question is WHEN should the user be able to interrupt/stop a program?

A- During a long running procedure / SQL
B- During a dialog execution
C- Both?

Seb


Title: Re: Configuring sigint
Post by: Stephen T. on October 22, 2013, 09:15:56 am
Seb,
Thanks for taking the time to look into this - but I never meant to create an 'issue'! I simply thought that I had missed a setting somewhere that made Genero behave the same as BDS when no DEFER and interrupt pressed. I am not advocating omitting DEFER INTERRUPT in Gnereo, it is just that this legacy BDS code uses that default behaviour .

I am quite happy (so far!) with how DEFER INTERRUPT works in Genero and have, even since the old Informix days, been used to coding around INT_FLAG.

In answer to your question though, if there was a specific (fglprofile?) setting to make Genero behave as BDS when no DEFER, then  I would guess that Genero would have to implement option C - or else again Genero would not be doing what BDS is (assuming what you say re BDS simply aborting on ^C no matter where in the code it was).

Steve


Title: Re: Configuring sigint
Post by: Sebastien F. on October 22, 2013, 10:20:56 am
Stephen,

Good to read that you are happy with the Genero behavior ;-)

We want to make migration from I4GL/BDS to Genero as easy as possible. However, we tend to avoid adding FGLPROFILE settings when it's not absolutely needed, because it makes the product more and more complex to use and test (imagine the combinations).

If you can manage to review the legacy code and use DEFER INTERRUPT/QUIT and INT_FLAG it's the best solution IMHO. I guess you don't want to have programs with different ergonomics. Make then all consistent.

Cheers!
Seb



Title: Re: Configuring sigint
Post by: Stephen T. on October 22, 2013, 11:41:27 am
Seb,
The programs aren't all coded the same way anyway - some do have DEFER and some don't. It just sods law that the section that I'm looking at at the moment do not use DEFER. I agree, that given there's no off the shelf 'quick fix' to get the same functionality, the best way forward is to put in the DEFERs.





Title: Re: Configuring sigint
Post by: Stephen T. on October 22, 2013, 06:43:46 pm
Seb,
Sorry to be a pain. The 'other' migration issues that have been found - as I say there are only a couple or so, and they aren't 'Genero' issues per se- so not really support type problems, just issues between BDS-Genero, that someone else may find handy to know before a migration. Do you want me still to send them to support for proving/forwarding on or do you want me to send them across off list?

Steve


Title: Re: Configuring sigint
Post by: Sebastien F. on October 23, 2013, 09:24:38 am
Hey Stephen no prob...

Our job is to help you to write your applications as easily as possible, with minimal migration efforts.
You have business logic to implement.
However, we want to keep the product simple, or make it even simpler.

Regarding the channel to report an issue:

Use the support channel if you face a bug or missing feature that can be clearly identified, and does not need a debate.

For other things / general discussions, this forum is the right place, so you can share issues to get help from other Genero users and from FourJs people, including implementers / designers.

Just create one thread / email per topic so we can easily follow up.

Cheers