static void ReAttachJob(Server server) { // get the current list of jobs Job[] jobs = server.getCurrentJobs(); if (jobs.Length > 0) { // let's re-attach on the job we created with the BasicScheduleJob // (it was scheduled on 1 minute from its submission time) Job existingJob = jobs[0]; for (int i = 0; i < jobs.Length; ++i) { if (jobs[i].Description == "BasicScheduleJob" && !jobs[i].hasEnded()) { existingJob = jobs[i]; } } Console.WriteLine("Reattaching to: {0}", existingJob); JobInteractor existingJobInteractor = new JobInteractor(); existingJob.JobInteractor = existingJobInteractor; // and do the same interaction loop as the one from the ScheduleJobAndCheckResult InteractLoop(existingJob, existingJobInteractor); } }
static void AdvancedInteraction(Server server) { // This example is similar to the ScheduleJobAndCheckResult, but the interaction is now more fine-grained ProcedureCall procedureCall = new ProcedureCall("proc_AdvancedInteraction", new Parameter(3.14), new StringParameter("abacadabra")); JobConfig jobConfig = new JobConfig(PRO_APPLICATION_NAME, PRO_APPLICATION_VERSION, "AdvancedInteraction", procedureCall); // create a new instance of the JobInteractor, which allows us to interact with the job JobInteractor jobInteractor = new JobInteractor(); Job job = server.scheduleJob(jobConfig, jobInteractor); AdvancedInteractLoop(job, jobInteractor); }
static void InteractLoop(Job job, JobInteractor jobInteractor) { // This is an example main-loop that will wait for events to happen on the remote job. bool done = false; bool finishHappened = false; do { // wait for some while to capture events from the pending job InteractiveJobEvent ev = jobInteractor.waitForEvent(TimeSpan.FromSeconds(1)); // because it is possible that events arrive in a different order in which they happened remotely, // we will wait one more time for incoming ProcedureCalls. This is done by setting 'finishHappened' // to true at the Finished event below. When we waited one time for other potential incoming messages, // after receiving the finish event, we deem this job really done. if (finishHappened) { done = true; } switch (ev) { case InteractiveJobEvent.TimeOut: // the specified amount of time (1 second) expired, do some other stuff Console.WriteLine("Waiting for events on job"); break; case InteractiveJobEvent.Error: string lastError = jobInteractor.firstIncomingError(); Console.WriteLine("error: {0}", lastError); // when we get errors, just terminate job.terminate(); done = true; break; case InteractiveJobEvent.ProcedureCall: ProcedureCall lastProcedureCall = jobInteractor.firstIncomingProcedureCall(); Console.WriteLine("procedureCall: {0}", lastProcedureCall.ProcedureName); // show what we retrieved DisplayProcedureCall(lastProcedureCall); break; case InteractiveJobEvent.Finished: Console.WriteLine("job Finished"); finishHappened = true; break; } } while (!done); }
static void AdvancedInteractLoop(Job job, JobInteractor jobInteractor) { bool done = false; bool finishHappened = false; int numberOfWaits = 0; do { // wait for some while to capture events from the pending job InteractiveJobEvent ev = jobInteractor.waitForEvent(TimeSpan.FromSeconds(1)); // because it is possible that events arrive in a different order in which they happened remotely, // we will wait one more time for incoming ProcedureCalls. This is done by setting 'finishHappened' // to true at the Finished event below. When we waited one time for other potential incoming messages, // after receiving the finish event, we deem this job really done. if (finishHappened) { done = true; } switch (ev) { case InteractiveJobEvent.TimeOut: // show some status Console.WriteLine("Waiting for events on job"); numberOfWaits++; // after waiting some time, inject a procedureCall to give us some progress updates // the AdvancedInteractProgress procedure sends (by issuing a DelegateToClient) // the desired progress updates, after that it continues where it left of the main // procedure if (numberOfWaits % 5 == 0) { Console.WriteLine("Requesting progress report"); ProcedureCall progressCall = new ProcedureCall("proc_AdvancedInteractProgress"); jobInteractor.inject(progressCall); } break; case InteractiveJobEvent.Error: string lastError = jobInteractor.firstIncomingError(); Console.WriteLine("error: {0}", lastError); // when we get errors, just terminate job.terminate(); done = true; break; case InteractiveJobEvent.ProcedureCall: ProcedureCall lastProcedureCall = jobInteractor.firstIncomingProcedureCall(); Console.WriteLine("procedureCall: {0}", lastProcedureCall.ProcedureName); // since we know we're only going to be called with one (scalar) parameter, // take some shortcuts here: Parameter p = (Parameter)lastProcedureCall.ProcedureArguments[0]; double fractionCompleted = p.Data[0].value; // let's check whether we think it's ok if (fractionCompleted > .75) { Console.WriteLine("Percentage completed = {0}%, enough, so stopping the current tast", fractionCompleted * 100.0); jobInteractor.stopTask(); // alternatively we might just stop the solver only, and continue our normal flow // for this example the solver is not running // jobInteractor.stopSolve(); } else { Console.WriteLine("Percentage completed = {0}%, not enough, continueing", fractionCompleted * 100.0); } break; case InteractiveJobEvent.Finished: Console.WriteLine("job Finished"); finishHappened = true; break; } } while (!done); }