I'm using Task Scheduler Managed Wrapper from Codeplex and I need to fire task as soon as possible and only once. I don't found any API that could execute created task immediately (I can be wrong). So how can I create a trigger that fires only once and as soon as possible?
Found solution here.
using (TaskService ts = new TaskService())
{
string task = "TaskName";
// This will find it even if its down in a folder. Alternately you could call:
// Task t = ts.GetTask(task);
Task t = ts.FindTask(task);
if (t != null)
t.Run();
}
Related
My Visual Studio code extension allows users to deploy and debug applications on remote devices.
To do this I need to have the application "installed" in a local folder that will then be synchronized to the target using rsync.
Some languages/tools provide a simple and standardized way to do this (ex: dotnet publish, for .NET core apps), others don't.
To be flexible and let users choose the method they prefer, my extension relies on a task with a specific name to perform the operation.
I have a resolveDebugConfiguration function that executes the task and then fills out the information inside debug connection to let user debug his app.
As long as this is a single task, this is not an issue. I can start it using vscode.tasks.executeTask and wait for its completion using OnEndTaskProcess. The task should be shell/process and a non-zero exit code means failure. I also check OnEndTask, to be sure that I don't miss other kinds of completition (ex: an invalid path in the cmd field or the user defined a custom task etc.).
Some users may want to have a more complex structure for this. For example having their deployment tasks depend on a build task, to ensure that the latest version is deployed, or perform additional operations in between, so I no longer have a single task, but a chain of tasks connected via dependson.
This is ok and still works...until it fails.
Or, better, until one of the dependency tasks fail.
In this case, I have no notification from OnEndTaskProcess or even OnEndTask and the tasks after the failed one remain inside vscode.tasks.taskExecutions list forever, it seems.
So my resolveDebugConfiguration function never returns and vscode remains in the "starting debugger" state forever...
My code looks like this:
// retrieve task given its name
const tasks = await vscode.tasks.fetchTasks();
var deploy: vscode.Task | undefined = undefined;
for (var task of tasks) {
switch (task.name) {
case "deploy":
deploy = task;
break;
}
}
if (deploy === undefined) {
// error message telling user that he has to define a task named "deploy"
return null;
}
var emitter = new EventEmitter();
// the process event arrives before the generic terminate one (checked inside vscode sources)
vscode.tasks.onDidEndTaskProcess(e => {
if (e.execution.task.name === "deploy") {
emitter.emit("terminated", e.exitCode);
}
});
vscode.tasks.onDidEndTask(e => {
// check if task is still running, otherwise report an error
var taskexecutions = vscode.tasks.taskExecutions;
for (var taskexecution of taskexecutions) {
if (taskexecution.task.name === "deploy") {
return;
}
}
emitter.emit("terminated", -1);
});
try {
var execution = await vscode.tasks.executeTask(deploy);
}
catch (e) {
// catch execution exceptions and show a message to the user
return null;
}
var code = await new Promise<Number>((resolve, reject) => {
emitter.on("terminated", code => resolve(code));
});
if (code !== 0) {
// deploy task failed
return null;
}
// local deployment succeeded, move on...
Some of the tasks may take a long time, so using a timeout may be a solution worse than the problem.
It would be nice to have OnEndTask called even when a dependency fails, preventing the actual task from running, but this does not seem to happen.
I plan to open an issue on vscode github repo, but maybe someone has a solution that doesn't involves changes to the ide itself.
I'm trying to implement a perpetual workflow that commences with an activity that blocks until a message is delivered (namely, Redis' BLPOP). Once it completes, I want to start a new workflow asynchronously to do some sort of processing and return ContinueAsNew immediately.
I've tried to start the processing workflow using child workflows. What I've observed is that my parent workflow completes before the child is executed. Unless I process the returned future, but I don't really want to do that.
What would be the right way to do this? Is it possible to start a new regular workflow within a workflow? Would such action be implemented as part of the workflow or within an activity?
Thank you in advance!
The solution is to wait for a child workflow to start before completing or continuing as new the parent.
If you are using the Go Cadence Client the workflow.ExecuteChildWorkflow returns a ChildWorkflowFuture which extends a Future that returns the child workflow result. It also has GetChildWorkflowExectution method that returns a Future that becomes ready as soon as the child is started. So to wait for a child workflow to start the following code can be used:
f := workflow.ExecuteChildWorklfow(ctx, childFunc)
var childWE WorkflowExecution
// The following line unblocks as soon as the child is started.
if err := f.GetChildWorkflowExecution().Get(&childWE); err != nil {
return err
}
Child workflow has started with Workflow ID found in childWE.ID and Run ID in childWE.RunID
The Java equivalent is:
ChildType child = Workflow.newChildWorkflowStub(ChildType.class);
// result promise becomes ready when the child completes
Promise<String> result = Async.function(child::executeMethod);
// childWE promise becomes ready as soon as the child is started
Promise<WorkflowExecution> childWE = Workflow.getWorkflowExecution(child);
I want to retrieve scheduled but already executed jobs from the scheduler in Quartz. Is there any way to do so?
Well, first you need to retrieve a list of all currently scheduled jobs:
Scheduler sched = new StdSchedulerFactory().getScheduler();
List jobsList = sched.getCurrentlyExecutingJobs();
Then, it's a matter of iterating the list to retrieve the context for reach job. Each context has a getPreviousFireTime().
Iterator jobsIterator = jobsList.listIterator();
List<JobExecutionContext> executedJobs = new List<JobExecutionContext>();
while(jobsIterator.hasNext())
{
JobExecutionContext context = (JobExecutionContext) jobsIterator.next();
Date previous = context.getPreviousFireTime();
if (previous == null) continue; //your job has not been executed yet
executedJobs.Add(context); //there's your list!
}
The implementation may be slightly different depending on which quartz you use (java or .net) but the principle is the same.
Set the property JobDetail.setDurability(true) - which instructs Quartz not to delete the Job when it becomes an "orphan" (when the Job not longer has a Trigger referencing it).
in my ASP.NET MVC3 Project, I've got an action which runs a certain amount of time.
It would be nice, if it could send partial responses back to the view.
The goal would be to show the user some progress-information.
Has anybody a clue how to make that work?
I did a try with some direct output to the response, but it's not being sent to the client in parts but all on one block:
[HttpPost]
public string DoTimeConsumingThings(int someId)
{
for (int i = 0; i < 10; i++)
{
this.Response.Write(i.ToString());
this.Response.Flush();
Thread.Sleep(500); // Simulate time-consuming action
}
return "Done";
}
In the view:
#Ajax.ActionLink("TestLink", "Create", new AjaxOptions()
{ HttpMethod = "POST", UpdateTargetId="ProgressTarget" })<br />
<div id="ProgressTarget"></div>
Can anybody help me making progressive action-results?
Thanks!!
Here's how you could implement this: start by defining some class which will hold the state of the long running operation -> you will need properties such as the id, progress, result, ... Then you will need two controller actions: one which will start the task and another one which will return the progress. The Start action will spawn a new thread to execute the long running operation and return immediately. Once a task is started you could store the state of this operation into some common storage such as the Application given the task id.
The second controller action would be passed the task id and it will query the Application to fetch the progress of the given task. During that time the background thread will execute and every time it progresses it will update the progress of the task in the Application.
The last part is the client: you could poll the progress controller action at regular intervals using AJAX and update the progress.
I've started using Quartz.NET recently, and so far, it's been really
helpful. Now, I'm trying to use it to create a job that runs once a
month using a NthIncludedDayTrigger (I want to use the
NthIncludedDayTrigger as eventually I will be specifying a calendar to
exclude weekends/holidays).
To familiarise myself with the code, I've
set up a simple console application to create an NthIncludedDayTrigger
where the first fire time will be 15 seconds from now:
static void Main(string[] args)
{
IScheduler scheduler = StdSchedulerFactory.DefaultScheduler;
scheduler.Start();
var jobDetail = new JobDetail("Job name", "Group name", typeof(SomeIJobImplementation));
var trigger = new NthIncludedDayTrigger();
trigger.Name = "Trigger name";
trigger.MisfireInstruction = MisfireInstruction.NthIncludedDayTrigger.DoNothing;
trigger.IntervalType = NthIncludedDayTrigger.IntervalTypeMonthly;
//I'm using the following while experimenting with the code (AddHour(1) to account for BST):
trigger.FireAtTime = DateTime.UtcNow.AddHours(1).AddSeconds(15).ToString("HH:mm:ss");
//I'm using the following while experimenting with the code:
trigger.N = DateTime.Today.Day;
Console.WriteLine("Started, press any key to stop ...");
Console.ReadKey();
scheduler.Shutdown(false);
}
...
public class SomeIJobImplementation : IJob
{
public void Execute(JobExecutionContext context)
{
Logger.Write(String.Format(
"Job executed called at {0}",
DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss")), null, 1,
TraceEventType.Information);
}
}
Running this results in the job being executed multiple times
(approximately once per second) for one minute. I'm using an ADO.NET
job store and can see in my database that QRTZ_TRIGGERS.NEXT_FIRE_TIME
is set to the last executed time, i.e. doesn't seem to be scheduled to
run again.
I expected the above code to run the job once (after about 15
seconds), then schedule the job to run again in one months time.
Perphaps the issue is just with the way I'm using Quartz.NET whilst
I've been experimenting or, maybe, my expectations are wrong? Either
way, I would be most grateful for any help/suggestions to explain the
behaviour I've observed, and what I need to change to get the
behaviour I want.
I must be late but I was trying to implement the same solution and ended up here.
I reckon you should star the scheduler after you've defined jobs and triggers.