Let a user ESCAPE from a loop without input control

Dear fellow Natural developers! :slight_smile:

In many of my programs I use some kind of loop (e.g. READ, FOR) that processes lots of entries and takes some time (hours) to run. To let the user see the progress of the program I print out the current iteration like this:

FOR #N 1 50000
  SET CONTROL 'N'
  INPUT (AD=IO) #N
END-FOR

However, if the user wants to abort the program it does not respond to his inputs due to SET CONTROL ‘N’:

SET KEY PF3
FOR #N 1 50000
  SET CONTROL 'N'
  INPUT (AD=IO) #N
  IF *PF-KEY EQ 'PF3' /* this does not work
    ESCAPE BOTTOM
  END-IF
END-FOR

Is there

  1. a way to abort such a loop according to the user’s input or
  2. any other way of keeping the user informed about the progress of the loop that can be aborted?

Best regards,
Stefan

The problem, of course, is that you want to use SET CONTROL ‘N’ to apprise the user of what is happening, and this does not allow for interaction with the user. If you add an INPUT without SET CONTROL ‘N’, you permit the user to interact, but you slow things down ( the user, of course, will be the slowest part of the processing).

The following code is as close as I think you will get to satisfying both of your requirements:

define data local
1 #loop (n8)
1 redefine #loop
2 filler 4x
2 #ten-thousand (a1)
2 #one-thousand (a1)
1 #end (a1)
1 #delay (i2) init <1>
end-define
*
for #loop = 1 to 100000
perform break processing

  • check for a thousands break
    at break of #one-thousand
    call ‘cmroll’ #delay
    set control ‘n’
    input 'up to iteration: ’ #loop (ad=o)
    end-break
  • now check if a ten thousand break
    at break of #ten-thousand
    input ‘do you wish to end processing? Y or N ==>’ #end
    if #end = ‘Y’
    stop
    end-if
    end-break
    end-for

end

The CALL CMROLL is just to slow things down so you can see what is happening. If you remove it, the up tp iteration message will be just a blur.

Of course, you would have to set the conditions for the two breaks. If you were reading through a file in logical sequence, by name, you might use the first letter of the name to control the second input and a counter within that break to control the first break.

Lots of variations of the code are possible, BUT, as noted above, you will have to establish the conditions for the two breaks.

steve

Dear Steve,

your solution does not work for me, because under normal circumstances the loop should run through without any user interaction at all (think of a program that runs really long, e.g. 40h like mine: nobody can sit in front of it that long). Only if the user spontaneously decides he wants to abort it (e.g. because he found a bug) it should be stopped.

What I’ve done before is to stow the program while it’s running or simply to close its session, but that leads to a hard abort without any possibility to clean up (e.g. close work files, end transactions).

I’ve come up with this solution (and it’s working fine for me), but I still would like to know if there is any other way to do this.

Function ABORT

DEFINE FUNCTION ABORT
  RETURNS (L)
ABORT := FALSE
END-FUNCTION
END

Loop

F1. FOR...
  IF ABORT(<>)
    PERFORM CLEAN-UP
    ESCAPE BOTTOM (F1.)
  END-IF
  /* normal loop processing
END-FOR

Now I can change the return value of ABORT to TRUE and stow the function during the loop’s runtine and have it abort cleanly. However, there are two tradeoffs with this approach:

  1. the overhead of calling ABORT in every loop iteration
  2. a normal user without access to the source code can still not abort the program

Best regards,
Stefan

Hi Stefan,

  1. You could do the IF ABORT only for the e.g. 10k iteration. This would limit the overhead.

Hi Stefan;

Instead of your current approach (which requires access to source code), How about having an external file? The user would have the responsibility to alter a value in what would be a work file.

This could be combined with Mogens idea of a counter controlling when to test for abort.

steve

Hi Stefan,

Perhaps the attention key (on unix I believe it is CTRL+C) can interrupt your program. On mf there must be an Adabas call in the loop to stop it. I do not have a unix available so I cannot test.

Hi Steve.

Yes, that would be a possibility. The overhead for reading the file could be compensated by only doing it evey nth iteration. Thanks for the idea. Although I would rather find a more “natural” way for the user to abort the program. I think I’ll take a closer look at what Morgens wrote:

Best regards,
Stefan

Mh… does anyone know how to enter attention keys in linux? What are the default key combinations used for them? CTRL-C and all the other usual suspects don’t seem to work (not recognized by *PF-KEY). I’ve tried it using our own terminal emulation and PuTTY.

Best regards,
Stefan