此文章是记录Deadline农场管理软件中的消息事件插件编写的示例。
事件插件的作用和执行顺序
Deadline 的所有插件都是Python写的,事件插件可用于更新新快照或任务的状态,或者可用于在一个作业状态更改时处理相关的作业。并且插件都是以非交互式的方式执行,编写插件时不应该包含阻塞操作(如无限循环)或需要用户输入的界面。当我们的事件插件被执行时,日志中会显示插件是从哪里加载的。
Deadline中有很多事件,事件插件的触发是按顺序的,并且顺序是可配置的:
创建事件脚本
首先要在存储库的custom\events文件夹中创建一个文件夹,并为其命名您的事件插件,如:
创建好文件夹后,我们需要新建一个和该文件夹相同明明的 .py 文件,并在文件中写入相应的基本内容(导入deadline事件命名空间;GetDeadlineEventListener()函数获取MyEvent类的一个实例,没有会报错;MyEvent类将需要基于想要响应的事件实现某些回调;当不再使用该事件插件,CleanupDeadlineEventListener()函数进行自动清理。):
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 进行读取,创建参数界面:
参数文件内容:
[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,在左边的列表中查找该事件插件。
至此,在 Deadline 中创建自定义任务消息失败/成功的事件已经完成,每当Deadline 中有任务失败时/成功时,Deadline 会自动给任务的提交者发送一条相关的消息弹框,用于给制作人员反馈及时的渲染消息。
注意:需要注意 Deadline 当前使用的 Python 版本,避免出现不兼容的情况
咱们有空可以看看官方文档是怎么说的,里面有更加详细的内容哦。
官方文档中事件脚本文档