Cinema 4D not triggering OnJobSubmitted in event plugin

Hey,

I’m putting together an event plugin that adjusts a few settings on submission of jobs to Deadline. I noticed that Cinema 4D jobs are not causing the event plugin to fire the OnJobSubmitted event when any other plugin (as far as I know) are triggering it. I only see the OnJobStarted and OnJobFinished.

Is this a known issue?

Hey Brett! Would you be comfortable sharing that script here? I’d like to play with it.

If not, feel free to send an e-mail over to us support folks at support@thinkboxsoftware.com

Certainly. It’s a bit rough and has a lot of work ahead.

import re
import sys
import traceback 
import platform

from System.IO import *
from System.Text import *

from Deadline.Events import *
from Deadline.Scripting import *


# Switch python version libraries
if "2.6" in platform.python_version():
    sys.path.append("\\\\ladev\\bb\\site-packages\\bb\\libs_26")
else:
    sys.path.append("\\\\ladev\\bb\\site-packages\\bb\\libs")

import pymongo
sys.path.append("\\\\ladev\\bb\\site-packages")

# Initialize bb module and reload it to generate fresh byte code (*.pyc)

import bb.pipeline
reload(bb.pipeline)

from bb.pipeline import Pipeline
from bb.constants import *


def GetDeadlineEventListener():
    return bbPipeline()


def header():
    log.info("-"*80)
    log.info("%s" % ("bbPipeline".center(80)))
    log.info("-"*80)
    
    
class bbPipeline (DeadlineEventListener):
    def __init__( self ):
        self.OnJobSubmittedCallback += self.OnJobSubmitted
        self.OnJobStartedCallback += self.OnJobStarted
        self.OnJobFinishedCallback += self.OnJobFinished
        self.OnJobRequeuedCallback += self.OnJobRequeued
        self.OnJobFailedCallback += self.OnJobFailed
    
    def OnJobSubmitted(self, job):
        # Note: Some reason Cinema4D is not calling this method ...
        header()
        
        # Department check
        log.info("Adjusting department...") 
        if job.JobUserName == "brett.bronson":
            log.info("User %s detected. Switching department to dev." % (job.JobUserName))
            job.JobDepartment = "dev"
            RepositoryUtils.SaveJob( job )
        else:
            
            # TODO: Add shortname lookup once that database is in place.
            
            # Apply project name for department
            project_list = []
            outputDirectories = job.JobOutputDirectories
            for i in range( 0, len(outputDirectories) ):
                # windows
                
                # TODO: Parse using Regex instead of splitting.
                
                project = ""
                # windows pathing
                if r"\\nox1" in outputDirectories[i].lower():
                    project = outputDirectories[i].split("\\")[5].lower()
                # mac pathing
                if "/volumes" in outputDirectories[i].lower():
                    project = outputDirectories[i].split("/")[3].lower()
                if project not in project_list:
                    project_list.append(project)

            if len(project_list) > 0:
                job.JobDepartment = project_list[0]
                RepositoryUtils.SaveJob( job )

            log.info("Checking per application submission settings...")
            if "nuke" in str(job.JobPlugin).lower():
                log.info(" - Checking Nuke settings...")
                # Our pipeline does not allow concurrent tasks for nuke since Mango
                # kills any nuke processes before beginning. 
                if int(job.JobConcurrentTasks) > 1:
                    log.info("   - Resetting Concurrent Tasks to 1. Our Pipeline doesn't support concurrent tasks at the moment.")
                    job.JobConcurrentTasks = 1
                    RepositoryUtils.SaveJob( job )

            
    def OnJobStarted(self, job):
        header()
        log.info("initializing pipeline object")
        p = Pipeline()
        log.info("Job status: %s" % (job.JobStatus))
        
        
    def OnJobRequeued(self, job):
        header()
        log.info("initializing pipeline object")
        p = Pipeline()
        log.info("Job status: %s" % (job.JobStatus))
        
        
    def OnJobFailed(self, job):
        header()
        log.info("initializing pipeline object")
        p = Pipeline()
        log.info("Job status: %s" % (job.JobStatus))
        
        
    def OnJobFinished( self, job ):
        header()
        log.info("initializing pipeline object")
        p = Pipeline()
        
        # Debug info
        log.info("Job.JobAuxiliarySubmissionFileNames: %s" % (job.JobAuxiliarySubmissionFileNames))
        log.info("Job.JobComment: %s" % (job.JobComment))
        log.info("Job.JobCompletedDateTime: %s" % (job.JobCompletedDateTime))
        log.info("Job.JobConcurrentTasks: %s" % (job.JobConcurrentTasks))
        log.info("Job.JobDependencyIDs: %s" % (job.JobDependencyIDs))
        log.info("Job.JobDependencyPercentageValue: %s" % (job.JobDependencyPercentageValue))
        log.info("Job.JobExtraInfo0: %s" % (job.JobExtraInfo0))
        log.info("Job.JobExtraInfo1: %s" % (job.JobExtraInfo1))
        log.info("Job.JobExtraInfo2: %s" % (job.JobExtraInfo2))
        log.info("Job.JobExtraInfo3: %s" % (job.JobExtraInfo3))
        log.info("Job.JobExtraInfo4: %s" % (job.JobExtraInfo4))
        log.info("Job.JobExtraInfo5: %s" % (job.JobExtraInfo5))
        log.info("Job.JobExtraInfo6: %s" % (job.JobExtraInfo6))
        log.info("Job.JobExtraInfo7: %s" % (job.JobExtraInfo7))
        log.info("Job.JobExtraInfo8: %s" % (job.JobExtraInfo8))
        log.info("Job.JobExtraInfo9: %s" % (job.JobExtraInfo9))
        log.info("Job.JobFrames: %s" % (job.JobFrames))
        log.info("Job.JobFramesList: %s" % (job.JobFramesList))
        log.info("Job.JobGroup: %s" % (job.JobGroup))
        log.info("Job.JobId: %s" % (job.JobId))
        log.info("Job.JobLimitGroups: %s" % (job.JobLimitGroups))
        log.info("Job.JobName: %s" % (job.JobName))
        log.info("Job.JobOnJobComplete: %s" % (job.JobOnJobComplete))
        log.info("Job.JobOutputDirectories: %s" % (job.JobOutputDirectories))
        log.info("Job.JobOutputFileNames: %s" % (job.JobOutputFileNames))
        log.info("Job.JobPlugin: %s" % (job.JobPlugin))
        log.info("Job.JobPool: %s" % (job.JobPool))
        log.info("Job.JobPriority: %s" % (job.JobPriority))
        log.info("Job.JobStatus: %s" % (job.JobStatus))
        log.info("Job.JobUserName: %s" % (job.JobUserName))

Well, I took if for a spin after taking some things out.

Where do you define “log”? Deadline expects either a call to “ClientUtils.LogText()” or “print()”.

I don’t remember where “ClientUtils” lives, but add an extra import just in case:
from FranticX.Utils import *

Edit:

I’m told it lives in Deadline.Scripting, so you’ll be good with your current imports

log is actually imported from the lines:

from bb.pipeline import Pipeline from bb.constants import *

it’s using the logging module that is packaged with Python.

Hi Brett,
When you submit a job from a particular machine can you share the local logs, as this should be displaying an error message as to why the event plugin is failing to execute correctly.
Thanks,
Mike

Where would I find the local logs for Cinema 4D? These submissions are coming from OSX. I tried looking at the Cinema 4D Console and I didn’t see any errors.

Hi Brett,
The OSX logs for Deadline are stored by default here: “/Library/Logs/Thinkbox/Deadline6/”
Can you zip up and send us the directory?
Thanks,
Mike

Okay, I’ve uploaded them to: http://mellow.me/tmp/dl_6_logs.zip

I noticed immediately in one of the logs this error:

2014-04-30 14:21:57: BEGIN - aceca010.bigblockla.local\design 2014-04-30 14:21:57: Events plugin 'bbPipeline' could not be loaded from the repository because: Error executing event plugin script "/Volumes/Deadline_Repository_6x/events/bbPipeline/bbPipeline.py": Python Error: ImportError : No module named pymongo (Python.Runtime.PythonException) 2014-04-30 14:21:57: Stack Trace: 2014-04-30 14:21:57: [' File "none", line 16, in <module>\n'] 2014-04-30 14:21:57: (Deadline.Events.DeadlineEventPluginException)

I believe this is an error on my part because I am appending to the system path in the module to load pymongo in bbPipeline.py, but didn’t account for Mac paths:

# Switch python version libraries
if "2.6" in platform.python_version():
    sys.path.append("\\\\ladev\\bb\\site-packages\\bb\\libs_26")
else:
    sys.path.append("\\\\ladev\\bb\\site-packages\\bb\\libs")

I guess I was under the impression that OnJobSubmitted was being triggered on farm, and not by the machine submitting. I think I’ll have to go through and map that location on our Mac user’s machines so they can access those modules.

Hi Brett,
Yep, that looks very much like the issue here. So, events such as onJobSubmitted or ( onJobDeleted, onJobSuspended when carried out by the right-click in monitor by a user ) are handled by the slave. So, in the case of “onJobSubmitted”, we want to locally submitting machine which has just submitted the job, to react to any events which might need handling. Whilst developing event plugins, I’d highly recommend keeping one eye on the logs, so you can see any issues as soon as they arise. Let us know if you need anymore help to finish off your plugin :slight_smile:
Mike