int Do(CWorkerNodeJobContext& context) { CNcbiIstream& is = context.GetIStream(); string input_type; is >> input_type; if (input_type != "doubles") { context.CommitJobWithFailure( "This worker node can only process the 'doubles' input type."); return 1; } int vsize; is >> vsize; vector<double> v(vsize); for (int i = 0; i < vsize; ++i) is >> v[i]; unsigned delay = m_SleepTimeDistr.GetNextValue(); if (delay > 0) SleepMilliSec(delay); if (m_Random.GetRand() < TParam_FailureRate::GetDefault() * m_Random.GetMax()) context.CommitJobWithFailure("FAILED"); else { sort(v.begin(), v.end()); CNcbiOstream& os = context.GetOStream(); os << vsize << ' '; for (int i = 0; i < vsize; ++i) os << v[i] << ' '; context.CommitJob(); } return 0; }
int Do(CWorkerNodeJobContext& context) { context.GetCleanupEventSource()->AddListener( new CSampleJobCleanupListener("Job-do")); LOG_POST( context.GetJobKey() + " " + context.GetJobInput()); LOG_POST( "This parameter is read from a config file: " << m_Param); // 1. Get an input data from the client // (You can use ASN.1 de-serialization here) // CNcbiIstream& is = context.GetIStream(); CNcbiOstream& os = context.GetOStream(); string output_type; is >> output_type; // could be "doubles" or "html" LOG_POST( "Output type: " << output_type); int count; is >> count; vector<double> dvec; dvec.reserve(count); LOG_POST( "Getting " << count << " doubles from stream..."); for (int i = 0; i < count; ++i) { if (!is.good()) { ERR_POST( "Input stream error. Index : " << i ); // If anything bad happened, throw an exception // and its message will be delivered to the client. throw runtime_error("Worker node input stream error"); } // Don't forget to check if shutdown has been requested if (count % 1000 == 0) switch (context.GetShutdownLevel()) { case CNetScheduleAdmin::eShutdownImmediate: case CNetScheduleAdmin::eDie: // Either this job is not needed anymore (canceled, // expired or already executed elsewhere), or the // server is going down and the job's execution // should be gracefully (yet urgently) aborted and // the job returned back to the network queue // for execution by other worker node instances. context.ReturnJob(); return 1; default: break; } double d; is >> d; dvec.push_back(d); } // 2. Doing some time consuming job here // Well behaved algorithm checks from time to time if // immediate shutdown has been requested and gracefully return // without calling context.CommitJob() // for (int i = 0; i < m_Iters; ++i) { switch (context.GetShutdownLevel()) { case CNetScheduleAdmin::eShutdownImmediate: case CNetScheduleAdmin::eDie: // Either this job is not needed anymore (canceled, // expired or already executed elsewhere), or the // server is going down and the job's execution // should be gracefully (yet urgently) aborted and // the job returned back to the network queue // for execution by other worker node instances. context.ReturnJob(); return 1; default: break; } context.PutProgressMessage("Iteration " + NStr::IntToString(i+1) + " from " + NStr::IntToString(m_Iters)); SleepSec(m_SleepSec); } sort(dvec.begin(), dvec.end()); // 3. Return the result to the client // (You can use ASN.1 serialization here) // // CNcbiOstream& os = context.GetOStream(); if (output_type == "html") os << "<html><head><title>" "Sample Grid Worker Result Page" "</title></head><body>" "<p>Sample Grid Worker Result</p>"; else os << dvec.size() << ' '; for (int i = 0; i < count; ++i) { if (!os.good()) { ERR_POST( "Output stream error. Index : " << i ); throw runtime_error("Worker node output stream error"); } os << dvec[i] << ' '; } if (output_type == "html") os << "</body></html>"; // 4. Indicate that the job is done and the result // can be delivered to the client. // context.CommitJob(); LOG_POST( "Job " << context.GetJobKey() << " is done."); return 0; }