此文章是记录Deadline农场管理软件中的消息事件插件编写的示例。

事件插件的作用和执行顺序

Deadline 的所有插件都是Python写的,事件插件可用于更新新快照或任务的状态,或者可用于在一个作业状态更改时处理相关的作业。并且插件都是以非交互式的方式执行,编写插件时不应该包含阻塞操作(如无限循环)或需要用户输入的界面。当我们的事件插件被执行时,日志中会显示插件是从哪里加载的。
Deadline中有很多事件,事件插件的触发是按顺序的,并且顺序是可配置的:

event顺序修改

创建事件脚本

首先要在存储库的custom\events文件夹中创建一个文件夹,并为其命名您的事件插件,如:

event创建事件文件夹

创建好文件夹后,我们需要新建一个和该文件夹相同明明的 .py 文件,并在文件中写入相应的基本内容(导入deadline事件命名空间;GetDeadlineEventListener()函数获取MyEvent类的一个实例,没有会报错;MyEvent类将需要基于想要响应的事件实现某些回调;当不再使用该事件插件,CleanupDeadlineEventListener()函数进行自动清理。):

event创建事件脚本文件

from Deadline.Events import *

def GetDeadlineEventListener():
    """This is the function that Deadline calls to get an instance of the
    main DeadlineEventListener class.
    """
    return MyEvent()

def CleanupDeadlineEventListener(deadlinePlugin):
    """This is the function that Deadline calls when the event plugin is
    no longer in use so that it can get cleaned up.
    """
    deadlinePlugin.Cleanup()

class MyEvent(DeadlineEventListener):
    """This is the main DeadlineEventListener class for MyEvent"""
    # TODO: Place code here to replace "pass"
    pass

当我们完成上述脚本文件的内容后,我们将会得到下面的脚本内容:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Auther: Mirror
# @Time: 2020/07/01
# =========================================
from System import *
from System.Collections.Specialized import *
from System.IO import *
from System.Text import *
from Deadline.Scripting import *
from Deadline.Events import *
import time


######################################################################
## This is the function that Deadline calls to get an instance of the
## main DeadlineEventListener class.
######################################################################
def GetDeadlineEventListener():
    return MyEvent()


######################################################################
## This is the function that Deadline calls when the event plugin is
## no longer in use so that it can get cleaned up.
######################################################################
def CleanupDeadlineEventListener(deadlinePlugin):
    deadlinePlugin.Cleanup()


######################################################################
## This is the main DeadlineEventListener class for MyEvent.
######################################################################
class MyEvent(DeadlineEventListener):

    def __init__(self):
        # Set up the event callbacks here
        self.OnJobFinishedCallback += self.OnJobFinished
        self.OnJobFailedCallback += self.OnJobFailed

    def Cleanup(self):
        del self.OnJobFinishedCallback
        del self.OnJobFailedCallback

    def OnJobFinished(self, job):
        # TODO: Connect to pipeline site to notify it that the job for a particular
        # shot or task is complete.
        job_name = job.JobName
        job_mach = job.GetJobInfoKeyValue("MachineName")
        job_user = job.JobUserName
        if job_mach.lower() == "renderfarm":
            slaves = None
        else:
            slaves = [job_mach]
        if slaves:
            for each in slaves:
                curr_time = time.strftime('%Y-%m-%d', time.localtime(time.time()))
                slave = each
                massages = "Cur_time:  {curtime}\nJob_user:  {user}\n\nmassages:  Job named \'{jobname}\' had been complate".format(
                    curtime=curr_time, user=job_user, jobname=job_name)
                self.sendmessages(slave, massages)
        print("================================================================================================")
        self.LogInfo("\'%s\' is complated" % job_name)
        self.LogInfo("================================================================================================")

    def OnJobFailed(self, job):
        """
        Deadline will to do sometion when job or task is faild
        :param job: which Work being monitored
        :return: None
        """
        job_name = job.JobName
        job_mach = job.GetJobInfoKeyValue("MachineName")
        job_user = job.JobUserName
        if job_mach.lower() == "renderfarm":
            slaves = ["DESKTOP-Mirror"]
        else:
            if job_mach == "DESKTOP-Mirror":
                slaves = [job_mach]
            else:
                slaves = [job_mach, "DESKTOP-Mirror"]
        for each in slaves:
            curr_time = time.strftime('%Y-%m-%d', time.localtime(time.time()))
            slave = each
            massages = "Cur_time:  {curtime}\nJob_user:  {user}\nmassages:  Job named \'{jobname}\' had been failed".format(
                curtime=curr_time, user=job_user, jobname=job_name)
            self.sendmessages(slave, massages)
        print("================================================================================================")
        self.LogInfo("\'%s\' is failed" % job_name)
        self.LogInfo("================================================================================================")

    def sendmessages(self, slaves, messages):
        """
        :param
            slaves: machines`s machines name or IP address.
            messages: the messages which is send by current serve]
        :return
            cmd is executed by system
        """
        args = StringCollection()
        args.Add("-SendPopupMessage")
        args.Add("%s" % slaves)
        args.Add("%s" % messages)
        ClientUtils.ExecuteCommand(args)

创建事件参数文件

创建完事件插件的脚本后,我们需要在上述文件夹中为事件插件添加与文件夹同名的参数文件(.param)供 Deadline 进行读取,创建参数界面:

event创建事件参数文件
参数文件内容:

[State]
Type=Enum
Items=Global Enabled;Opt-In;Disabled
Category=Options
CategoryOrder=0
Index=0
Label=State
Default=Disabled
Description=How this event plug-in should respond to events. If Global, all jobs and slaves will trigger the events for this plugin. If Opt-In, jobs and slaves can choose to trigger the events for this plugin. If Disabled, no events are triggered for this plugin.

[EventCallbacks]
Type=Label
Description=The Event Callbacks that this Event Plugin subscribes to.
Default=OnJobFailed

它将声明 Monitor 用来生成用户界面的属性,该用户界面用于修改数据库中的自定义设置,创建该文件后,打开监视器并进入超级用户模式。然后选择Tools -> Configure Events,在左边的列表中查找该事件插件。

event事件插件配置

至此,在 Deadline 中创建自定义任务消息失败/成功的事件已经完成,每当Deadline 中有任务失败时/成功时,Deadline 会自动给任务的提交者发送一条相关的消息弹框,用于给制作人员反馈及时的渲染消息。

注意:需要注意 Deadline 当前使用的 Python 版本,避免出现不兼容的情况

咱们有空可以看看官方文档是怎么说的,里面有更加详细的内容哦。

官方文档中事件脚本文档