Page 1 of 1

Creating new job via script

Posted: Thu Aug 06, 2015 1:57 pm
by DtM
Hello!

I was wondering if anyone could offer me some insight as to why my script is unable to create a new file and output it into my flow.

Here is the script I have written attempting to do so:

Code: Select all

// Is invoked each time a new job arrives in one of the input folders for the flow element.
// The newly arrived job is passed as the second parameter.
function jobArrived( s : Switch, job : Job )
{
}

// Is invoked at regular intervals regardless of whether a new job arrived or not.
// The interval can be modified with s.setTimerInterval().
function timerFired( s : Switch )
{
	s.log(3,'Tick.');
	var slowInterval = 600; // Number of seconds between unfruitful searches
	var fastInterval = 10; // Number of seconds between job yielding searches
	var maxLines = 10;  // Number of lines to attempt processing before requerying the database

	var select1 = "SELECT order_id, line_number, line_id, url " +
				  "FROM table_name AS tn " +
				  "LEFT JOIN other_table AS o ON o.id = tn.order_id " +
				  "WHERE tn.status = 'READY' AND o.status = 'READY' " +
				  "ORDER BY order_id, tn.line_number;"
					
	var jobLinkDS = new DataSource();
	
	jobLinkDS.connect("JL-DEV");

	var selectQuery = new Statement(jobLinkDS);
	var updateQuery = new Statement(jobLinkDS);
	
	selectQuery.execute(select1);
	
	var activeOrder = 0;	
	
	for (i = 0; i < maxLines; i++) {
		if (selectQuery.isRowAvailable()) {
			s.setTimerInterval(fastInterval);
			selectQuery.fetchRow();
			s.log(3,'loop run ' + (i+1));
			
			orderID = selectQuery.getString(0);
			lineNum = selectQuery.getString(1);
			lineID = selectQuery.getString(2);
			URL = selectQuery.getString(3);

			if (activeOrder == 0) {
				activeOrder = orderID;
			} else if (activeOrder != orderID) {
				s.log(3, "New Order ID. Restarting.");				
				return;
			}

			var newFile = new File(s.createPathWithName("#" + orderID + "-#" + lineID + "(" + lineNum + ").dg"));
			
			s.log(3, newFile.fullName);
			
			var newJob = s.createNewJob(newFile.fullName);
			
			newJob.setPrivateData("orderID", orderID);
			newJob.setPrivateData("lineNum", lineNum);
			newJob.setPrivateData("lineID", lineID);
			newJob.setPrivateData("URL", URL);
			
			newJob.sendToSingle(newFile.fullName);
			
			var update1 = "UPDATE table_name SET status = 'IN SWITCH' WHERE line_id = " + parseInt(lineID,10);
			
			updateQuery.execute(update1);
			
		} else {
			s.setTimerInterval(slowInterval);
			return;
		}		
	}
}
To summarise what the script should actually be doing:
  • Check the database to see if there is a suitable job
  • If there is, generate a dummy .dg file and attach relevant information as private data
  • Output the file into the flow, where the private data can be actioned upon
Everything seems to be working fine, except for the actual output of the file, does anyone have any idea why this might be?

Many thanks,

Dan

Re: Creating new job via script

Posted: Thu Aug 06, 2015 3:47 pm
by gabrielp
Can you try changing this:

Code: Select all

newJob.sendToSingle(newFile.fullName);
To this:

Code: Select all

newJob.sendToSingle(newJob.getPath());
I think sendToSingle() is expecting a job path.

Re: Creating new job via script

Posted: Thu Aug 06, 2015 4:08 pm
by DtM
Thanks for the advice, but it doesn't make any difference unfortunately.

Re: Creating new job via script

Posted: Thu Aug 06, 2015 5:34 pm
by gabrielp
How about this?

Code: Select all

// Is invoked each time a new job arrives in one of the input folders for the flow element.
// The newly arrived job is passed as the second parameter.
function jobArrived( s : Switch, job : Job )
{
}

// Is invoked at regular intervals regardless of whether a new job arrived or not.
// The interval can be modified with s.setTimerInterval().
function timerFired( s : Switch )
{
   s.log(3,'Tick.');
   var slowInterval = 600; // Number of seconds between unfruitful searches
   var fastInterval = 10; // Number of seconds between job yielding searches
   var maxLines = 10;  // Number of lines to attempt processing before requerying the database

   var select1 = "SELECT order_id, line_number, line_id, url " +
              "FROM table_name AS tn " +
              "LEFT JOIN other_table AS o ON o.id = tn.order_id " +
              "WHERE tn.status = 'READY' AND o.status = 'READY' " +
              "ORDER BY order_id, tn.line_number;"
               
   var jobLinkDS = new DataSource();
   
   jobLinkDS.connect("JL-DEV");

   var selectQuery = new Statement(jobLinkDS);
   var updateQuery = new Statement(jobLinkDS);
   
   selectQuery.execute(select1);
   
   var activeOrder = 0;   
   
   for (i = 0; i < maxLines; i++) {
      if (selectQuery.isRowAvailable()) {
         s.setTimerInterval(fastInterval);
         selectQuery.fetchRow();
         s.log(3,'loop run ' + (i+1));
         
         orderID = selectQuery.getString(0);
         lineNum = selectQuery.getString(1);
         lineID = selectQuery.getString(2);
         URL = selectQuery.getString(3);

         if (activeOrder == 0) {
            activeOrder = orderID;
         } else if (activeOrder != orderID) {
            s.log(3, "New Order ID. Restarting.");            
            return;
         }
 
		 
		  // Put job name in a variable for later
		  jobKey = "#" + orderID + "-#" + lineID + "(" + lineNum + ").dg";
		 
		  // Create a new job container
		  newJob = s.createNewJob( jobKey );
		  newJobPath = newJob.createPathWithName( jobKey, false );
		  
		  // Log
         s.log(3, newFile.fullName);
		 
		  // Set private data        
         newJob.setPrivateData("orderID", orderID);
         newJob.setPrivateData("lineNum", lineNum);
         newJob.setPrivateData("lineID", lineID);
         newJob.setPrivateData("URL", URL);
         
		  // Update query
         var update1 = "UPDATE table_name SET status = 'IN SWITCH' WHERE line_id = " + parseInt(lineID,10);
         
         updateQuery.execute(update1);
		 
		 // Send to single
         newJob.sendToSingle( newJobPath );
         
      } else {
         s.setTimerInterval(slowInterval);
         return;
      }      
   }
}

Re: Creating new job via script

Posted: Fri Aug 07, 2015 9:40 am
by DtM
It still doesn't output any files strangely.

Let's go back to basics. Ignoring all of my database and private data needs, what would be a simple way to generate a blank file and output it every iteration of timeFired?

Stripping the code you gave me back down to it's basics, something like this should work:

Code: Select all

function timerFired( s : Switch )
{

	fileName = "test.dg";

	newJob = s.createNewJob(fileName);
	newJobPath = newJob.createPathWithName(fileName, false)

	newJob.sendToSingle(newJobPath);
	
}
But I still don't get anything out of the script. I've double checked and I've definitely got the script outgoing connections set to one.

This is quite the mystery... :?

Re: Creating new job via script

Posted: Fri Aug 07, 2015 11:59 am
by bens
Hi,

The problem is you're not creating a file on disk.

First you create a new job:

Code: Select all

newJob = s.createNewJob(fileName);
This creates a job object in Switch, but that job is not associated to any specific file or folder. The parameter to the createNewJob function is the job's origin - it's basically just metadata recorded in the job ticket.

Then you create a temp path:

Code: Select all

newJobPath = newJob.createPathWithName(fileName, false)
This tells Switch you want a location, somewhere in a temp folder, to create a file called "test.dg". No file is being created at this point: the call just returns a path where you can create a file.

Code: Select all

newJob.sendToSingle(newJobPath);
Finally, this tell Switch to send the file at path newJobPath to the single outgoing connection. But there is no file there, remember you only asked for a path but did not create a file yet.

The shortest code to create an empty file is with the static File.write function:

Code: Select all

File.write( newJobPath, "" );
So putting it all together, this should work:

Code: Select all

function timerFired( s : Switch )
{
   var fileName = "test.dg";

   var newJob = s.createNewJob(fileName);
   var newJobPath = newJob.createPathWithName(fileName, false);
   
   File.write( newJobPath, "" );

   newJob.sendToSingle(newJobPath);
}

Re: Creating new job via script

Posted: Fri Aug 07, 2015 12:53 pm
by DtM
And there you have it, it's now outputting.

In the original script, I had the line:

Code: Select all

var newFile = new File(s.createPathWithName("#" + orderID + "-#" + lineID + "(" + lineNum + ").dg"));
I had assumed that this was sufficient enough to create the file, but apparently not.

Here is my full code that now works as intended:

Code: Select all

// Is invoked each time a new job arrives in one of the input folders for the flow element.
// The newly arrived job is passed as the second parameter.
function jobArrived( s : Switch, job : Job )
{
}

// Is invoked at regular intervals regardless of whether a new job arrived or not.
// The interval can be modified with s.setTimerInterval().
function timerFired( s : Switch )
{
   s.log(3,'Tick.');
   var slowInterval = 600; // Number of seconds between unfruitful searches
   var fastInterval = 10; // Number of seconds between job yielding searches
   var maxLines = 10;  // Number of lines to attempt processing before requerying the database

   var select1 = "SELECT order_id, line_number, line_id, url " +
              "FROM table_name AS tn " +
              "LEFT JOIN other_table AS o ON o.id = tn.order_id " +
              "WHERE tn.status = 'READY' AND o.status = 'READY' " +
              "ORDER BY order_id, tn.line_number;"
               
   var jobLinkDS = new DataSource();
   
   jobLinkDS.connect("JL-DEV");

   var selectQuery = new Statement(jobLinkDS);
   var updateQuery = new Statement(jobLinkDS);
   
   selectQuery.execute(select1);
   
   var activeOrder = 0;   
   
   for (i = 0; i < maxLines; i++) {
      if (selectQuery.isRowAvailable()) {
         s.setTimerInterval(fastInterval);
         selectQuery.fetchRow();
         s.log(3,'loop run ' + (i+1));
         
         orderID = selectQuery.getString(0);
         lineNum = selectQuery.getString(1);
         lineID = selectQuery.getString(2);
         URL = selectQuery.getString(3);

         if (activeOrder == 0) {
            activeOrder = orderID;
         } else if (activeOrder != orderID) {
            s.log(3, "New Order ID. Restarting.");            
            return;
         }
 
       
        // Put job name in a variable for later
        jobKey = "#" + orderID + "-#" + lineID + "(" + lineNum + ").dg";
       
        // Create a new job container
        newJob = s.createNewJob( jobKey );
        newJobPath = newJob.createPathWithName( jobKey, false );
        
        // Log
         s.log(3, newFile.fullName);
       
        // Set private data        
         newJob.setPrivateData("orderID", orderID);
         newJob.setPrivateData("lineNum", lineNum);
         newJob.setPrivateData("lineID", lineID);
         newJob.setPrivateData("URL", URL);
        
       // Write the file
         File.write(newJobPath, "");
         	               
       // Send to single
         newJob.sendToSingle( newJobPath );
         
       // Update query
         var update1 = "UPDATE table_name SET status = 'IN SWITCH' WHERE line_id = " + parseInt(lineID,10);
         
         updateQuery.execute(update1);
         
      } else {
         s.setTimerInterval(slowInterval);
         return;
      }      
   }
}
Thank you very much to both of you for your help. :D

Re: Creating new job via script

Posted: Fri Aug 07, 2015 3:51 pm
by gabrielp
I also assumed it would have created an empty file, but going back and looking at my older scripts (https://github.com/dominickp/SwitchAWS/ ... ad.js#L125), I do see that I am writing to the file so that makes sense.

Thanks for the explanation, bens.