Snowflake tasks that calls a stored procedure to only finish once the procedure is done running - stored-procedures

For a project, I am calling a stored procedure through a Snowflake task. As long as a task is running, it cannot be called again. Since it only consists of calling the stored procedure, the task will finish quickly and before the stored procedure is done.
Due to our wish for close to real-time scheduling (and uncertainty of the exact time the condition for running the procedure will be True) the task will be called again while the procedure is still running. This won't cause an error, but it isn't the best style. A task cannot be called again for as long as it is running.
Does anyone have experience with having a task run as long as the stored procedure it calls?
Maybe using procedural logic?

Related

DB2 LUW 10.5 - How to force DB2 Stored procedures to use latest stats for most optimized plan

We see an issue occasionally. Stored procedure running a SQL runs very slow. Same SQL when run from command line runs very fast. It seems stored procedure uses a different path. The workaround for us is to drop and recreate the procedure, after which it picks up the right plan.
Is there a way to execute a stored procedure with an instruction to regenerate execution plan at run time, so as to get the best plan every time.
You probably don't want to recompile plans every time you call your procedure, as you lose the performance benefit of having the procedure in the first place.
When you do need to recompile it, which shouldn't happen too frequently in a stable environment, you can use the REBIND_ROUTINE_PACKAGE system stored procedure:
call SYSPROC.REBIND_ROUTINE_PACKAGE('P', 'YOUR_SP', '')
If you do decide that you want the plan to be recreated each time the procedure is called, you can set the REOPT ALWAYS bind option when you create the procedure, using the many ways described in the manual, for example by executing call SYSPROC.SET_ROUTINE_OPTS('REOPT ALWAYS) before creating the procedure

Delphi Application Run

The Application.Run procedure calls an infinite loop that handles windows messages:
repeat
try
HandleMessage;
except
HandleException(Self);
end;
until Terminated;
The Terminated property can be set to true only through Application.Terminate procedure, which sends PostQuitMesage.
I would like to change the message handling loop so that I can directly stop it using the global variable (without using messages queue):
var MyTerminated:Boolean
....
repeat
try
HandleMessage;
except
HandleException(Self);
end;
until Terminated or MyTerminated;
The question is, is it possible to make the program use your own version of Application.Run?
"Terminated" property is read-only. However it is a direct getter of the FTerminated field, therefore Application.Terminated directly reads from the boolean field. While the language disallows setting Application.Terminated, you can set the boolean value at that address using a pointer:
PBoolean(#Application.Terminated)^ := True;
You may also consider using Halt, which will pass over the message loop completely, for a more abrupt but less hacky solution.
Yes, you can make your application use own version of Application run, but this practice is discouraged, because it changes normal program flow, designed by the architects of Delphi.
Directly stopping Application.Run signifies that there is a need to restart Application.Run later, for example, after some action that is wanted to be done from the main thread. This makes the program puzzled, harder to understand by peer programmers and more error prone as a whole.
The program design should be simple and straightforward. If an application is big, for example two million lines of code, the overall design of the execution flow should be simple anyway:
If you need to do some longer actions, do them from the worker threads;
If you need to do an instant actions, do them from your main form or from the other forms.
So a Delphi application main loop should only be exited on the overall application exit, which is done by the PostQuitMessage. We don't have to avoid this message.
The reason why PostQuitMessage is wanted to be avoided, is probably an instantaneous exit. This is not how VCL applications are supposed to run. If one doesn't need forms (for example for a Windows Service application), just don't use the TApplication class an don't run forms, just make your own message loop based on MsgWaitForMultipleObjects.

Stored procedures fire and forget with Entity Framework

I am using the Entity Framework 4.1 within an application. One of the requirments is to execute some stored procedures on the database out of which some take quite some time. Further, those stored procedures do not return any results so I need to only start them and forget about them.
Naturally, .NET will wait for these operations to complete so after some time it throws an exception that the "Timeout period has expired".
I know that I could fix that by setting the CommandTimeout property to a higher value, however I am looking for an alternative solution (If such even exists).
Is it possible to execute stored procedures using the Entity Framework as Fire-and-Forget?
Any help will be appreciated.
Regards
Stored procedures don't support fire and forget execution. You can either use plain ADO.NET and execute query asynchronously on separate connection (with BeginExecuteNonQuery). EF doesn't support asynchronous execution. Another more complex way which behaves like fire and forget is creating SQL Job with single step execution your stored procedure. Instead of calling your stored procedure you will call sp_start_job which returns immediately after starting the job and job will execute asynchronously without returning any other result back to your application.

How do I check for PROGRAM idle time, as opposed to SYSTEM idle time?

I have a program that occasionally needs to scan some directories recursively (an improvement for this part of the program is in the pipeline, but won't be ready for a while). To avoid the user having to wait for this scanning, I would like to do the scanning while the user isn't using my program when possible.
I intend to implement it by running a timer that checks for idle time. I've found the following for checking system idle time:
http://www.delphitips.net/2007/11/11/how-to-detect-system-idle-time/
This would be functional, but I would prefer to activate the function even when the user is working with other programs on the same computer. This way, if he switches to another program, I could catch up on the scanning I need to do.
I realize that I could do the scanning in a background thread, and either that or some sort of windows hooks will be implemented at some point, but not just yet.
EDIT:
The goal here is a relatively easy change to the program to do any scanning that might be queued while the user isn't actively using MY application. The scanning isn't especially intensive, but it isn't done in a thread, and therefore freezes my app while in progress. Basically, I'm looking for a quick win while I'm working on a more long term solution.
Use the Application.OnIdle event. That event is triggered when your program has no more window messages to handle. The keyboard and mouse both generate messages, so if there are no more messages, then the user is not using your program, even if it has the focus.
procedure TJasonForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
var
NoMoreFiles: Boolean;
begin
// TODO: Scan for the next file
Done := NoMoreFiles;
end;
As long as Done is False and there are no messages in the queue, your program will continue to call that event handler, allowing you to find more files. When the user generates some input, your program will handle the messages before calling OnIdle again.
When you've finished scanning the file system, set Done to True so that the program stops re-calling the OnIdle handler. If you neglect to do that, then your program will use all available CPU time repeatedly calling an event handler that does nothing.
For this to work, you'll need to use a non-recursive search routine. A recursive search will search the whole file system before returning, but if you do that, then the OnIdle handler will hang your program, which is the oposite of what you want. You can use a queue of directory names, and each time the event is fires, pop one item off the queue, search it, and add its contents to the end of the queue.
...but I would prefer to activate the
function even when the user is working
with other programs on the same
computer. This way, if he switches to
another program, I could catch up on
the scanning I need to do.
Stop the scanning in Application.OnActivate and resume in Application.OnDeactivate.
What you need is a separate thread that will be resumed when the system is idle or paused when there is activity. A simple way to do this is to place a Timer Component and check if the system is idle and thread is suspended or not use ResumeThread ,SuspendThread
Look here
http://pastebin.com/8X9Sg42H i crafted something for your situation enjoy

TTimer Stops by itself

I am using TTimer in my software and it supposed to run forever 24/7. Nowhere in my software is that timer disabled or stopped from running. It's main function is to update table's value. It is started as soon as the software is run and from that point on TTimer should not stop. However, after running for over a month, that TTimer mysteriously stops running. The software is run on Windows 7 and the software is developed on Delphi 2010 XE. I've searched my code to see what might be causing it, but I can't figure out what.
Timer1.Enabled:=true;
That's how the timer is started.
UPDATE:
After doing some investigation, I found out that the TTimer never stopped, but there is another issue. My TStringGrid table on a TForm just simply don't show any values being updated. Further, I also found out that my TList List I am using to store list of data item is being destroyed somehow that the list becomes empty. But the data items in the list are not deleted anywhere in the code once they are loaded only when the program is started.
Everytime I update the TStringGrid on the form, I run through my TList items from 0 to count-1 location. So, if there is no item in the TList in the memory, my code simply skips
over the display part and thus nothing gets updated on the TStringGrid.
Something like:
If (List.count>0) then
begin
//Display values in TStringGrid;
end;
But while the software is still running, I was able to reload my list of items from a file
back into TList list and my software started to work like it supposed.
I hate to say the ugliest word programmers hate the most. I am afraid I may have a memory leak. Anyone think so?
Any help will be greatly appreciated. Thanks.
I bet it stops 49 days after reboot. When Windows GetTickCount wraps around. Sure you're not doing a check that would fail based on this?
TTimer is just a wrapper around the Windows SetTimer() API which I believe will run forever.
I suspect that the timer still runs, but the event handler that it fires is failing to operate as desired.
I'm not sure why it's stopping after a month; I'd suspect (as Erik said) you have something using GetTickCount() that's failing after the wraparound at ~49 days.
As a general rule, though, it's better to stop/start the timer to prevent a delay from causing a timer message to be dropped:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
try
// Do whatever on timer event firing
finally
Timer1.Enabled := True;
end;
end;
You might try this instead of just allowing it to run constantly; if it is a bug in the TTimer code (I don't see anything after a quick scan of XE's TTimer implementation), stopping and starting may reset things to prevent the failure.
You should free memory allocated after the job is done:
Timer1.FreeOnRelease() or .Free();

Resources