Forum OpenACS Development: Schedule a procedure to run on 1st of every month in project open.

I want a procedure to run on 1st of every month in Project Open.
I tried using:

bind time - "00 00 01 * *" time:proc

proc time:proc { min hour day month year } {
...
}

but this throws an error: "time" is not a procedure

Can i use this with some modifications to run error free? Or is there any other way to run the procedure on 1st of every month inside Project Open??

Thanks in advance..

This is how I do monthly scheduled procedures:

ad_schedule_proc -thread t -schedule_proc ns_schedule_daily [list 0 0] proc_name_here

This actually runs the procedure every day at midnight, but the next part is this:

In the procedure you're running daily, check to see which day of the month it is. In my case, I make sure it's the first day of each month at the very beginning. If it's not, then I do nothing, otherwise, the procedure will continue.

if {[clock format [clock seconds] -format "%e"] != 1} { return }

A more elegant method may exist, but this is how I've done it for a long time, and it works fine.

Thanks Nathan,

But, My functionality needs to re-run the procedure as and when required. If I use the way you did then it may only run on the 1st of every month. The case of running it again as and when required will fail. Sorry, for not intimating about this functionality earlier. Please suggest me a way to run the proc on 1st and also the user must have a provision to run it again, if needed..

Thanks again..

Thanks Nathan,

But, My functionality needs to re-run the procedure as and when required. If I use the way you did then it may only run on the 1st of every month. The case of running it again as and when required will fail. Sorry, for not intimating about this functionality earlier. Please suggest me a way to run the proc on 1st and also the user must have a provision to run it again, if needed..

Thanks again..

OK, define exactly what these things mean; don't leave anything out...

"as required", "when required", "user must have a provision", "if needed"

and define them in the context of what you want specifically here and now.

also what version of project open do you run?

which version of aolserver, which version of postgres, which version of the underlying openacs do you run?

In my functionality.. On the 1st of month if the AOL or the system goes down while running my procedure, The user will be insisted to run the process again. That he need to do manually.(I will provide a link for him to do so). So, I need a command to run the procedure on 1st of every month and also run it when it is invoked.

**Version details**
AOL Version: 4.5.1
Project Open Version: 3.4.0.8.9
Win32-OpenACS technology

Hope you got the details. Please let me know how can I run my procedure according to this above mentioned functionality.

Hi Madhavi,

Just call your proc in your link target.

Hey Ryan,

Calling the proc in my link target will not help because the proc has a condition that it will run only on 1st of every month.

If you have a solution, Can you please make it clear?

Hi Madhavi,

Please explain why your proc needs to filter by time when you're actually scheduling the proc

-Jim

Hey Jim,

I dont need any filter by time functionality. I want my proc to run on 1st of every month. And also it must run as and when it is called.

I have explained the details, what all I need in the previous posts. Please go through it and let me know the solution.

You have circular logic, both in your proc and in your explanations. remove the circular logic from both, and refactor.

If I can be of service in doing actual coding, I am available on a contract basis.

-Jim

The technical part is not complicated, I believe the primary issues are in how your trial solution is designed and in how it is factored. As mentioned above, you need to factor such that the function you call is not dependent on the time. If you refactor in this way, you will (1) be able to call it from a link and (2) will also be able to schedule it, or wrap it in a scheduler which may have been defined by project/open or that you might define.

In https://openacs.org/forums/message-view?message_id=3438041 you say:

I dont need any filter by time functionality.
Good point. I agree, you do not need such filtering. But, in https://openacs.org/forums/message-view?message_id=3437903 you say:
Calling the proc in my link target will not help because the proc has a condition that it will run only on 1st of every month.
So I have one question about that. Why do you have this filtering functionality you know you don't need?

You use bind, but bind is associated with events from the X window system, something you don't use (I am given to understand from your writings that you use ms windows); from the man page for bind:

NAME
bind - Arrange for X events to invoke Tcl scripts

You posted this...

proc time:proc { min hour day month year } {
...
}

is this the proc you wish to run? or, do you want to create a proc that schedules a proc of constant name?

When and under what conditions do you intend to run time:proc? What is it meant to do?

Please make it easy to understand your intent; trying to guess is a useless waste of time. It's evident your full intent is not completely explained since you're asking more questions and changing the requirements in mid-query.

I happen to hold the opinion that we can create something that will work, and to the extent you're willing to cooperate in asking for help, I'm willing to supply some help to you as long as that fits within my schedule. Please don't forget we're volunteering to help (for example, we are NOT paid support for project/open). Your cooperation is requested as we all notice that all of us, yourself, myself and everyone listening to this deserves respect for their time.

I would like to let you know about ad_proc; you can look that up in the api browser.

Hey Jim,

The "bind time" itself acts as a scheduler. Inside the time:proc(just a proc name, which is scheduled by the bind) we need to mention our procedure which need to be scheduled. Madhavi has already mentioned in her first post about calling the time:proc by the

bind time - "00 00 01 * *" time:proc

As you said about the ad_proc, I agree with that. Here the issue is "bind time" thing is not supported in Project Open. So Madhavi is requiring an alternative to that.
As far as Madhavi's issue is concerned, may be the "cronjob" package is the remedy for that. I suggest to try that.

Cheers..

-IQBAL

Heya IQBAL...

Just a look at how the wind is presently blowing... I've checked with tcl devs, they say support for tcl-8.4 is hanging by a thread, so you might test p/o with aolserver-4.5.x and tcl-8.5; the tcl folks are saying that there are fewer bugs, more support and an interesting little list feature that's kinda like an iterated shell backquote, turns a list appearing as a single parameter, into each item of the list as a parameter.

I know oct is aware of this, and they made some decisions about future openacses; check with them to see what they decided about tcl.

Before there are too much rumors in this thread:

Concerning the "bind" command floating around in this thread: If you are talking about the "bind" from the tcl/tk manuals, the discussion is pointless, since "bind" is a tk command, not available in tcl only apps (such as aolserver) and not particulary useful for the discussed functionality either. i can't exclude that there is a tcl proc named "bind" provided by ]po[.

Concerning Tcl 8.4 and 8.5: I fail to see any connection to this topic. However the sitation is as follows: The Tcl Core Team wrote more than two years ago: "Routine maintenance of Tcl/Tk 8.4 has now come to an end". So, OCT decided to switch to Tcl 8.5:
http://www.openacs.org/forums/message-view?message_id=3357449

I guess many of as are not sure, what the problem is. one can easily provide e.g. a parameter for a fproc foo to determine, whether you want to run it manually or not. In the example below, just call "foo" without parameter to call it manually...
ad_proc -public foo {
    {-batch_p 0}
} {
    @param patch_p run only on every 1st
} {
    # guard run in "batched mode"
    if {$batch_p && [clock format [clock seconds] -format "%e"] != 1} { 
	return 
    }
    # otherwise just do it

    ns_log notice "running "
}

# ... register with parameter for batched mode
ad_schedule_proc -thread t -schedule_proc ns_schedule_daily [list 0 0] foo -batch_p 1
Hi Gustaf,

This will solve the problem partially. As I don't need to call my procedure daily. Please provide something like "bind -time", which works in Project Open to run my procedure on 1st of every month and also to manually invoke the procedure.

Madhavi,

the solution i have pasted allows you to call an anytime foo maually. The function will be called as well every day, but the guard makes sure that the function body will be called only on the 1st of every month. Otherwise the function will return doing nothing.

Ok, last attempt: To make the behavior even more explicit, which one can use of many different functions should be called on every 1st:
define a function run_on_every_first and pass it an argument to a plain function (without guard):

proc -public run_on_every_first {proc args} {
    if {[clock format [clock seconds] -format "%e"] != 1} {
        # it is not the first, do nothing 
	return 
    }

    # use eval in case, proc has arguments
    eval $proc $args
}

# ... register which proc should be run on every 1st.
ad_schedule_proc -thread t -schedule_proc ns_schedule_daily [list 0 0] run_on_every_first YOUR_FUNCTION

Anyhow, if you have more complex needs (there are no indications from your postings), maybe the cronjob package can help you:
http://cvs.openacs.org/browse/OpenACS/openacs-4/packages/cronjob