Record Flush in handler doesn't work


Boguslaw Uryga
 

I had an idea to simply write a record to disk before zooming to another program, to ensure that the called program sees all changes made in calling one.

I tested this in the following simple setup:

ProgramA
   - browse, allow modify, with zoom [Button]  on the form
   - handler on Event=Zoom, Ctrl=[Buttom], with two lines: Raise Event 'Record Flush'action and Call Program: ProgramB (Param=RecordID)

ProgramB (Param=RecordID)
   - screen to show the record with the passed ID

I tried different settings of Wait, Flow, Propagate options, 'Screen Refresh'act, 'View Refresh'act and even IF( stat(0,'q'mode), 'Query Records'act, 'Modify Records'act ) but it refuses to work.

Do you have any idea why doesn't it work or know any simple way to do it?   

Boguslaw.


sherman levine
 

I think the underlying issue is that the internal events are added to the processing buffer, while the call program is executed immediately.

One approach is to have the button trigger two buffered events

    Record flush (wait=no)

    User action ## (wait=no)

and have the user action handler call program B.

That will force the record flush to complete before the user action is triggered.

Sherm


On 01/30/2017 09:13 AM, Boguslaw Uryga wrote:
I had an idea to simply write a record to disk before zooming to another program, to ensure that the called program sees all changes made in calling one.

I tested this in the following simple setup:

ProgramA
   - browse, allow modify, with zoom [Button]  on the form
   - handler on Event=Zoom, Ctrl=[Buttom], with two lines: Raise Event 'Record Flush'action and Call Program: ProgramB (Param=RecordID)

ProgramB (Param=RecordID)
   - screen to show the record with the passed ID

I tried different settings of Wait, Flow, Propagate options, 'Screen Refresh'act, 'View Refresh'act and even IF( stat(0,'q'mode), 'Query Records'act, 'Modify Records'act ) but it refuses to work.

Do you have any idea why doesn't it work or know any simple way to do it?   

Boguslaw.


Boguslaw Uryga
 

Thanks Sherm,

We used that workaround for years but it is little annoying to write doubled handlers over and over again. Besides it clutters the task view and logic. 

Getting things done (and simple I would add) !




2017-01-30 15:29 GMT+01:00 sherman levine <slevine@...>:

I think the underlying issue is that the internal events are added to the processing buffer, while the call program is executed immediately.

One approach is to have the button trigger two buffered events

    Record flush (wait=no)

    User action ## (wait=no)

and have the user action handler call program B.

That will force the record flush to complete before the user action is triggered.

Sherm


On 01/30/2017 09:13 AM, Boguslaw Uryga wrote:
I had an idea to simply write a record to disk before zooming to another program, to ensure that the called program sees all changes made in calling one.

I tested this in the following simple setup:

ProgramA
   - browse, allow modify, with zoom [Button]  on the form
   - handler on Event=Zoom, Ctrl=[Buttom], with two lines: Raise Event 'Record Flush'action and Call Program: ProgramB (Param=RecordID)

ProgramB (Param=RecordID)
   - screen to show the record with the passed ID

I tried different settings of Wait, Flow, Propagate options, 'Screen Refresh'act, 'View Refresh'act and even IF( stat(0,'q'mode), 'Query Records'act, 'Modify Records'act ) but it refuses to work.

Do you have any idea why doesn't it work or know any simple way to do it?   

Boguslaw.



sherman levine
 

You can put everything into a single handler if you choose to

Handler for event EVENT

If (RunPassTwo)
    Update RunPassTwo to false
    Call program B
else
    Update RunPassTwo to True
    Record flush
    Raise event (EVENT)
EndIf





On 01/30/2017 10:05 AM, Boguslaw Uryga wrote:
Thanks Sherm,

We used that workaround for years but it is little annoying to write doubled handlers over and over again. Besides it clutters the task view and logic. 

Getting things done (and simple I would add) !




2017-01-30 15:29 GMT+01:00 sherman levine <slevine@...>:

I think the underlying issue is that the internal events are added to the processing buffer, while the call program is executed immediately.

One approach is to have the button trigger two buffered events

    Record flush (wait=no)

    User action ## (wait=no)

and have the user action handler call program B.

That will force the record flush to complete before the user action is triggered.

Sherm


On 01/30/2017 09:13 AM, Boguslaw Uryga wrote:
I had an idea to simply write a record to disk before zooming to another program, to ensure that the called program sees all changes made in calling one.

I tested this in the following simple setup:

ProgramA
   - browse, allow modify, with zoom [Button]  on the form
   - handler on Event=Zoom, Ctrl=[Buttom], with two lines: Raise Event 'Record Flush'action and Call Program: ProgramB (Param=RecordID)

ProgramB (Param=RecordID)
   - screen to show the record with the passed ID

I tried different settings of Wait, Flow, Propagate options, 'Screen Refresh'act, 'View Refresh'act and even IF( stat(0,'q'mode), 'Query Records'act, 'Modify Records'act ) but it refuses to work.

Do you have any idea why doesn't it work or know any simple way to do it?   

Boguslaw.




Boguslaw Uryga
 

Does it mean that during the handler lines execution the event queue is not interpreted ?

Boguslaw.
 

2017-01-30 15:29 GMT+01:00 sherman levine <slevine@...>:

I think the underlying issue is that the internal events are added to the processing buffer, while the call program is executed immediately.

One approach is to have the button trigger two buffered events

    Record flush (wait=no)

    User action ## (wait=no)

and have the user action handler call program B.

That will force the record flush to complete before the user action is triggered.

Sherm


On 01/30/2017 09:13 AM, Boguslaw Uryga wrote:
I had an idea to simply write a record to disk before zooming to another program, to ensure that the called program sees all changes made in calling one.

I tested this in the following simple setup:

ProgramA
   - browse, allow modify, with zoom [Button]  on the form
   - handler on Event=Zoom, Ctrl=[Buttom], with two lines: Raise Event 'Record Flush'action and Call Program: ProgramB (Param=RecordID)

ProgramB (Param=RecordID)
   - screen to show the record with the passed ID

I tried different settings of Wait, Flow, Propagate options, 'Screen Refresh'act, 'View Refresh'act and even IF( stat(0,'q'mode), 'Query Records'act, 'Modify Records'act ) but it refuses to work.

Do you have any idea why doesn't it work or know any simple way to do it?   

Boguslaw.



Boguslaw Uryga
 

Thanks Sherm, that's a good idea.

In the meatime I tested this in event handler:

Raise Event 'Record Flush'
Select Virtual vDelay Logical
Update vDelay with Delay(10)
Call ProgramB
Raise Event 'View Refresh'

and the changes from ProgramA show up in ProgramB and then changes from ProgramB show up in ProgramA.

This is of course not reliable in production cause the execution of Record Flush is time dependant and can or can't be expected.

Still looking for a simpler solution ......

Boguslaw.



2017-01-30 16:09 GMT+01:00 sherman levine <slevine@...>:

You can put everything into a single handler if you choose to

Handler for event EVENT

If (RunPassTwo)
    Update RunPassTwo to false
    Call program B
else
    Update RunPassTwo to True
    Record flush
    Raise event (EVENT)
EndIf






On 01/30/2017 10:05 AM, Boguslaw Uryga wrote:
Thanks Sherm,

We used that workaround for years but it is little annoying to write doubled handlers over and over again. Besides it clutters the task view and logic. 

Getting things done (and simple I would add) !




2017-01-30 15:29 GMT+01:00 sherman levine <slevine@...>:

I think the underlying issue is that the internal events are added to the processing buffer, while the call program is executed immediately.

One approach is to have the button trigger two buffered events

    Record flush (wait=no)

    User action ## (wait=no)

and have the user action handler call program B.

That will force the record flush to complete before the user action is triggered.

Sherm


On 01/30/2017 09:13 AM, Boguslaw Uryga wrote:
I had an idea to simply write a record to disk before zooming to another program, to ensure that the called program sees all changes made in calling one.

I tested this in the following simple setup:

ProgramA
   - browse, allow modify, with zoom [Button]  on the form
   - handler on Event=Zoom, Ctrl=[Buttom], with two lines: Raise Event 'Record Flush'action and Call Program: ProgramB (Param=RecordID)

ProgramB (Param=RecordID)
   - screen to show the record with the passed ID

I tried different settings of Wait, Flow, Propagate options, 'Screen Refresh'act, 'View Refresh'act and even IF( stat(0,'q'mode), 'Query Records'act, 'Modify Records'act ) but it refuses to work.

Do you have any idea why doesn't it work or know any simple way to do it?   

Boguslaw.





Boguslaw Uryga
 

Oh, sorry.  The delay method doesn't work at all. I have run another copy of test program, ha, ha.

Boguslaw.


2017-01-30 16:40 GMT+01:00 Boguslaw Uryga <b_uryga@...>:

Thanks Sherm, that's a good idea.

In the meatime I tested this in event handler:

Raise Event 'Record Flush'
Select Virtual vDelay Logical
Update vDelay with Delay(10)
Call ProgramB
Raise Event 'View Refresh'

and the changes from ProgramA show up in ProgramB and then changes from ProgramB show up in ProgramA.

This is of course not reliable in production cause the execution of Record Flush is time dependant and can or can't be expected.

Still looking for a simpler solution ......

Boguslaw.




2017-01-30 16:09 GMT+01:00 sherman levine <slevine@...>:
You can put everything into a single handler if you choose to

Handler for event EVENT

If (RunPassTwo)
    Update RunPassTwo to false
    Call program B
else
    Update RunPassTwo to True
    Record flush
    Raise event (EVENT)
EndIf






On 01/30/2017 10:05 AM, Boguslaw Uryga wrote:
Thanks Sherm,

We used that workaround for years but it is little annoying to write doubled handlers over and over again. Besides it clutters the task view and logic. 

Getting things done (and simple I would add) !




2017-01-30 15:29 GMT+01:00 sherman levine <slevine@...>:

I think the underlying issue is that the internal events are added to the processing buffer, while the call program is executed immediately.

One approach is to have the button trigger two buffered events

    Record flush (wait=no)

    User action ## (wait=no)

and have the user action handler call program B.

That will force the record flush to complete before the user action is triggered.

Sherm


On 01/30/2017 09:13 AM, Boguslaw Uryga wrote:
I had an idea to simply write a record to disk before zooming to another program, to ensure that the called program sees all changes made in calling one.

I tested this in the following simple setup:

ProgramA
   - browse, allow modify, with zoom [Button]  on the form
   - handler on Event=Zoom, Ctrl=[Buttom], with two lines: Raise Event 'Record Flush'action and Call Program: ProgramB (Param=RecordID)

ProgramB (Param=RecordID)
   - screen to show the record with the passed ID

I tried different settings of Wait, Flow, Propagate options, 'Screen Refresh'act, 'View Refresh'act and even IF( stat(0,'q'mode), 'Query Records'act, 'Modify Records'act ) but it refuses to work.

Do you have any idea why doesn't it work or know any simple way to do it?   

Boguslaw.






Wes Hein
 

Have you tried a Post Record Update event?

Wes 


Florian Groothuis
 

What I usually do is the following:

 

Event ButtonClick sets a Virtual to True and performs a RecordFlush

Event DoStuff sets that same virtual to False and is triggered by that virtual in the RecordPrefix

 

 

 

Van: main@magicu-l.groups.io [mailto:main@magicu-l.groups.io] Namens Boguslaw Uryga
Verzonden: maandag 30 januari 2017 16:06
Aan: main@magicu-l.groups.io
Onderwerp: Re: [magicu-l] Record Flush in handler doesn't work

 

Thanks Sherm,

We used that workaround for years but it is little annoying to write doubled handlers over and over again. Besides it clutters the task view and logic. 

Getting things done (and simple I would add) !


 

 

 

2017-01-30 15:29 GMT+01:00 sherman levine <slevine@...>:

I think the underlying issue is that the internal events are added to the processing buffer, while the call program is executed immediately.

One approach is to have the button trigger two buffered events

    Record flush (wait=no)

    User action ## (wait=no)

and have the user action handler call program B.

That will force the record flush to complete before the user action is triggered.

Sherm

 

On 01/30/2017 09:13 AM, Boguslaw Uryga wrote:

I had an idea to simply write a record to disk before zooming to another program, to ensure that the called program sees all changes made in calling one.

I tested this in the following simple setup:

ProgramA
   - browse, allow modify, with zoom [Button]  on the form
   - handler on Event=Zoom, Ctrl=[Buttom], with two lines: Raise Event 'Record Flush'action and Call Program: ProgramB (Param=RecordID)

ProgramB (Param=RecordID)
   - screen to show the record with the passed ID

I tried different settings of Wait, Flow, Propagate options, 'Screen Refresh'act, 'View Refresh'act and even IF( stat(0,'q'mode), 'Query Records'act, 'Modify Records'act ) but it refuses to work.

Do you have any idea why doesn't it work or know any simple way to do it?   

Boguslaw.

 

 

Met vriendelijke groet - With kind regards,

Florian Groothuis
Analist/programmeur
+31 (0)6 21927914


meilink.eu

Meilink Beheer Borculo B.V. • Kamerlingh Onnesstraat 1
7271 AZ  Borculo • Nederland • +31 (0)545 253525
KvK 08009803 • Our general terms and conditions apply • Disclaimer



Boguslaw Uryga
 

At last I have found this working:

Event Handler:  Call ProgramB => Call Properties => Sync Data=Yes

BUT as it is said in help, it woks only in Deferred, Nested Deferred, Withi Active Transaction. For Physical transactions the option is dimmed.

Does anybody have an experience with the use of Sync Data property? Any caveats and restrictions?





2017-01-30 17:04 GMT+01:00 Florian Groothuis <f.groothuis@...>:

What I usually do is the following:

 

Event ButtonClick sets a Virtual to True and performs a RecordFlush

Event DoStuff sets that same virtual to False and is triggered by that virtual in the RecordPrefix

 

 

 

Van: main@magicu-l.groups.io [mailto:main@....io] Namens Boguslaw Uryga
Verzonden: maandag 30 januari 2017 16:06
Aan: main@magicu-l.groups.io
Onderwerp: Re: [magicu-l] Record Flush in handler doesn't work

 

Thanks Sherm,

We used that workaround for years but it is little annoying to write doubled handlers over and over again. Besides it clutters the task view and logic. 

Getting things done (and simple I would add) !


 

 

 

2017-01-30 15:29 GMT+01:00 sherman levine <slevine@...>:

I think the underlying issue is that the internal events are added to the processing buffer, while the call program is executed immediately.

One approach is to have the button trigger two buffered events

    Record flush (wait=no)

    User action ## (wait=no)

and have the user action handler call program B.

That will force the record flush to complete before the user action is triggered.

Sherm

 

On 01/30/2017 09:13 AM, Boguslaw Uryga wrote:

I had an idea to simply write a record to disk before zooming to another program, to ensure that the called program sees all changes made in calling one.

I tested this in the following simple setup:

ProgramA
   - browse, allow modify, with zoom [Button]  on the form
   - handler on Event=Zoom, Ctrl=[Buttom], with two lines: Raise Event 'Record Flush'action and Call Program: ProgramB (Param=RecordID)

ProgramB (Param=RecordID)
   - screen to show the record with the passed ID

I tried different settings of Wait, Flow, Propagate options, 'Screen Refresh'act, 'View Refresh'act and even IF( stat(0,'q'mode), 'Query Records'act, 'Modify Records'act ) but it refuses to work.

Do you have any idea why doesn't it work or know any simple way to do it?   

Boguslaw.

 

 

Met vriendelijke groet - With kind regards,

Florian Groothuis
Analist/programmeur
+31 (0)6 21927914


meilink.eu

Meilink Beheer Borculo B.V. • Kamerlingh Onnesstraat 1
7271 AZ  Borculo • Nederland • +31 (0)545 253525
KvK 08009803 • Our general terms and conditions apply • Disclaimer




Steven Blank
 

Boguslaw,

'Record Flush'ACT is an Internal Event. Type Internal events cannot be raised synchronously (Wait=Yes); internal events can ONLY be raised asynchronously (Wait=No).

Events that are raised asynchronously (Wait=No) are never processed immediately; instead, they are added to the event queue where they will be processed in the future and in the same sequence in which they were queued (FIFO).

At runtime in an online task, the runtime engine only checks the event queue during its interactive phase, that is, when the runtime engine is ready to accept user input. In older parlance, the interactive phase is when task execution is within the Record Main.

Thus, events raised asychronously will only be processed during the interactive phase of task execution.

Steve Blank


Boguslaw Uryga
 

Thanks Steven,

You have confirmed my suspicions.

Generally we need two kind of programming techniques for different situations: parallel (asynchronous, event driven) and sequential (procedural). Sometimes we can not rely on events to code a sequence of actions because we can not strictly predict the execution order or execution end time of actions (eg. in heavy loaded envirnment).

In my example, most common and obvious one, there should be a function RecordFlush() complementary to 'Record Flush'ACT to save a dataview before calling child program. Magic has this function internally but it is only triggered by the event action and is not available to programmer (as every other function handling internal events). Hence we have to base on tricks and workarounds instead of simple solutions.

Boguslaw.

Getting things simple,
Getting things better,
Getting things done.



2017-01-30 20:44 GMT+01:00 Steven Blank <sgblank@...>:

Boguslaw,

'Record Flush'ACT is an Internal Event. Type Internal events cannot be raised synchronously (Wait=Yes); internal events can ONLY be raised asynchronously (Wait=No).

Events that are raised asynchronously (Wait=No) are never processed immediately; instead, they are added to the event queue where they will be processed in the future and in the same sequence in which they were queued (FIFO).

At runtime in an online task, the runtime engine only checks the event queue during its interactive phase, that is, when the runtime engine is ready to accept user input. In older parlance, the interactive phase is when task execution is within the Record Main.

Thus, events raised asychronously will only be processed during the interactive phase of task execution.

Steve Blank






Keith Canniff
 

Boguslaw,

 

Well there’s always the upside down approach to this (eliminating the Record Flush issue). Start with the line items as the main file and link to the header. That way when you commit the line item, you commit the header. No need for a sync because it’s automatic. You also only commit the header when the line item is committed. No more orphaned detail lines without a header.

 

The above it typically paired with a header lookup program for searching, but when you drill down (Zoom), you go through the above.

When you return to the header lookup, you issue a Screen Refresh so that the data on the screen shows the changes (or addition) on the header record.

 

Just a thought and doesn’t work for all situations, but the alternative is what you’ve already seen.

 

HTH

 

Keith

 

From: main@magicu-l.groups.io [mailto:main@magicu-l.groups.io] On Behalf Of Boguslaw Uryga
Sent: Monday, January 30, 2017 1:49 PM
To: main@magicu-l.groups.io
Subject: Re: [magicu-l] Record Flush in handler doesn't work

 

Thanks Steven,

You have confirmed my suspicions.

Generally we need two kind of programming techniques for different situations: parallel (asynchronous, event driven) and sequential (procedural). Sometimes we can not rely on events to code a sequence of actions because we can not strictly predict the execution order or execution end time of actions (eg. in heavy loaded envirnment).

In my example, most common and obvious one, there should be a function RecordFlush() complementary to 'Record Flush'ACT to save a dataview before calling child program. Magic has this function internally but it is only triggered by the event action and is not available to programmer (as every other function handling internal events). Hence we have to base on tricks and workarounds instead of simple solutions.

Boguslaw.

Getting things simple,

Getting things better,
Getting things done.

 

 

2017-01-30 20:44 GMT+01:00 Steven Blank <sgblank@...>:

Boguslaw,

'Record Flush'ACT is an Internal Event. Type Internal events cannot be raised synchronously (Wait=Yes); internal events can ONLY be raised asynchronously (Wait=No).

Events that are raised asynchronously (Wait=No) are never processed immediately; instead, they are added to the event queue where they will be processed in the future and in the same sequence in which they were queued (FIFO).

At runtime in an online task, the runtime engine only checks the event queue during its interactive phase, that is, when the runtime engine is ready to accept user input. In older parlance, the interactive phase is when task execution is within the Record Main.

Thus, events raised asychronously will only be processed during the interactive phase of task execution.

Steve Blank



 




Avast logo

This email has been checked for viruses by Avast antivirus software.
www.avast.com



Boguslaw Uryga
 

Hi Keith,

I couldn't agree more. I have a different approach/solution in many programs suitable for different needs (multilevel document, tree of objects, etc.). Today I tried to revise my knowledge while scanning throuh a very old program from the early days.

I will test Sync Data=Yes property of Call Program.  It looks promising but it could be done carefully cause deferred transactions are involved.  It works on a single station but things can go worse on battle field :)

Boguslaw.


2017-01-31 0:21 GMT+01:00 Keith Canniff <kcanniff@...>:

Boguslaw,

 

Well there’s always the upside down approach to this (eliminating the Record Flush issue). Start with the line items as the main file and link to the header. That way when you commit the line item, you commit the header. No need for a sync because it’s automatic. You also only commit the header when the line item is committed. No more orphaned detail lines without a header.

 

The above it typically paired with a header lookup program for searching, but when you drill down (Zoom), you go through the above.

When you return to the header lookup, you issue a Screen Refresh so that the data on the screen shows the changes (or addition) on the header record.

 

Just a thought and doesn’t work for all situations, but the alternative is what you’ve already seen.

 

HTH

 

Keith

 

From: main@magicu-l.groups.io [mailto:main@....io] On Behalf Of Boguslaw Uryga
Sent: Monday, January 30, 2017 1:49 PM
To: main@magicu-l.groups.io
Subject: Re: [magicu-l] Record Flush in handler doesn't work

 

Thanks Steven,

You have confirmed my suspicions.

Generally we need two kind of programming techniques for different situations: parallel (asynchronous, event driven) and sequential (procedural). Sometimes we can not rely on events to code a sequence of actions because we can not strictly predict the execution order or execution end time of actions (eg. in heavy loaded envirnment).

In my example, most common and obvious one, there should be a function RecordFlush() complementary to 'Record Flush'ACT to save a dataview before calling child program. Magic has this function internally but it is only triggered by the event action and is not available to programmer (as every other function handling internal events). Hence we have to base on tricks and workarounds instead of simple solutions.

Boguslaw.

Getting things simple,

Getting things better,
Getting things done.

 

 

2017-01-30 20:44 GMT+01:00 Steven Blank <sgblank@...>:

Boguslaw,

'Record Flush'ACT is an Internal Event. Type Internal events cannot be raised synchronously (Wait=Yes); internal events can ONLY be raised asynchronously (Wait=No).

Events that are raised asynchronously (Wait=No) are never processed immediately; instead, they are added to the event queue where they will be processed in the future and in the same sequence in which they were queued (FIFO).

At runtime in an online task, the runtime engine only checks the event queue during its interactive phase, that is, when the runtime engine is ready to accept user input. In older parlance, the interactive phase is when task execution is within the Record Main.

Thus, events raised asychronously will only be processed during the interactive phase of task execution.

Steve Blank



 




Avast logo

This email has been checked for viruses by Avast antivirus software.
www.avast.com