task是代码执行的地方。task通过target互相依赖。

下面是一个典型的task的大纲视图。

一、Task.requires

requires方法用来指定本task的依赖的其他task对象,依赖的task对象甚至可以是同一个class的对象,下面是一个例子:

def requires(self):
return OtherTask(self.date), DailyReport(self.date - datetime.timedelta(1))

上述的DailyReport task依赖两个task,其中一个是同类型的。从这里也可以看出requires方法可以返回多个依赖的task对象,这些对象可以封装在一个dict、list或者tuple中。

二、requiring another task

注意requires不能返回一个target对象,如果你的task依赖一个简单的target对象,那么你要为这个target对象生成一个task class。例如下面这个例子:

class LogFiles(luigi.ExternalTask):
def output(self):
return luigi.contrib.hdfs.HdfsTarget('/log')

这样做也方面你使用参数来控制:

class LogFiles(luigi.ExternalTask):
date = luigi.DateParameter()
def output(self):
return luigi.contrib.hdfs.HdfsTarget(self.date.strftime('/log/%Y-%m-%d'))

三、Task.output

output方法可以返回一个或者多个target对象。和requires方法一样,你可以使用容器来随意包装。

但是我们非常希望每一个task只会返回一个target对象在output方法中。如果对个对象被返回,那么你的task就必须保证每一个target都是原子被创建的。

当然如果不关注原子性,那么返回多个target对象也是安全的。

例子:

class DailyReport(luigi.Task):
date = luigi.DateParameter()
def output(self):
return luigi.contrib.hdfs.HdfsTarget(self.date.strftime('/reports/%Y-%m-%d'))
# ...

四、Task.run

run方法是包含实际运行的代码。当你同时使用了Task.requires和Task.run那么luigi会把这个分成两个阶段。

首先luigi需要计算出task之间的依赖关系,然后依次执行。input方法是一个很好的辅助方法,他对应着依赖对象的output方法。

下面是一个例子:

class GenerateWords(luigi.Task):

    def output(self):
return luigi.LocalTarget('words.txt') def run(self): # write a dummy list of words to output file
words = [
'apple',
'banana',
'grapefruit'
] with self.output().open('w') as f:
for word in words:
f.write('{word}\n'.format(word=word)) class CountLetters(luigi.Task): def requires(self):
return GenerateWords() def output(self):
return luigi.LocalTarget('letter_counts.txt') def run(self): # read in file as list
with self.input().open('r') as infile:
words = infile.read().splitlines() # write each word to output file with its corresponding letter count
with self.output().open('w') as outfile:
for word in words:
outfile.write(
'{word} | {letter_count}\n'.format(
word=word,
letter_count=len(word)
)
)

五、task.input

input方法保证了task.requires返回的对应的target对象。task.requires返回的任何东西都会被转换,包括list,dict等等。这是非常有用的,当你task有多个依赖的时候。下面是一个例子:

class TaskWithManyInputs(luigi.Task):
def requires(self):
return {'a': TaskA(), 'b': [TaskB(i) for i in xrange(100)]} def run(self):
f = self.input()['a'].open('r')
g = [y.open('r') for y in self.input()['b']]

六、Dynamic dependencies

有时可能会发生这样的情况,在运行之前你不能确切的知道本task依赖于哪一个task对象。在这种情况下,luigi提供了一种机制来指定动态依赖。

如果你在task.run方法中yield了另一个task对象,那么当前的task会被挂起并且这个被yield的task会运行。你也可以yield一系列的task。

例子:

class MyTask(luigi.Task):
def run(self):
other_target = yield OtherTask() # dynamic dependencies resolve into targets
f = other_target.open('r')

这种机制和task.requires只能二中选一。但是这也带了很多的限制,你必须保证你的task.run方法是幂等的。

七、task status tracking

对于长时间运行的作业,你可以通过命令行或者日志或者中央调度器的GUI界面来看到任务的进度信息。

你可以再task.run方法中指定一个额外的监控系统。你可以如下这么设置:

class MyTask(luigi.Task):
def run(self):
# set a tracking url
self.set_tracking_url("http://...") # set status messages during the workload
for i in range(100):
# do some hard work here
if i % 10 == 0:
self.set_status_message("Progress: %d / 100" % i)

八、events and callbacks

luigi有一个内置的event系统允许你注册回调函数给event。

你可以同时使用预定义的event和你自定义的event。

每一个event handle都是与一个task class相关的,它也只能被这个class或者其subclass来触发。

这允许你轻松的订阅event从一个特殊的类,比如hadoop jobs

@luigi.Task.event_handler(luigi.Event.SUCCESS)
def celebrate_success(task):
"""Will be called directly after a successful execution
of `run` on any Task subclass (i.e. all luigi Tasks)
"""
... @luigi.contrib.hadoop.JobTask.event_handler(luigi.Event.FAILURE)
def mourn_failure(task, exception):
"""Will be called directly after a failed execution
of `run` on any JobTask subclass
"""
... luigi.run()

九、运行hadoop job

你可以这么直接运行一个hadoop job,而不是用luigi

MyJobTask('abc', 123).run()

你也可以直接使用HdfsTarget class

t = luigi.contrib.hdfs.target.HdfsTarget('/tmp/test.gz', format=format.Gzip)
f = t.open('w')
# ...
f.close() # needed

十、task priority

luigi调度下一个作业运行时根据优先级的。默认情况下是随意选择执行的,这个适合大多数的场景。

如果你想人为的控制执行顺序,那么可以设置task的priority:

# A static priority value as a class constant:
class MyTask(luigi.Task):
priority = 100
# ... # A dynamic priority value with a "@property" decorated method:
class OtherTask(luigi.Task):
@property
def priority(self):
if self.date > some_threshold:
return 80
else:
return 40
# ...

优先级的值越高越优先执行。优先级没有一个确切的范文,你可以随意指定一个int或者float的值作为优先级。默认值是0。

注意:优先级是需要考虑依赖的,依赖没有执行,优先级最高也没什么用。

十一、instance caching

luigi提供了一个元类逻辑,如果

DailyReport(datetime.date(2012, 5, 10))

被实例化了两次,其实在luigi中是同一个对象。

luigi学习5-task详解的更多相关文章

  1. 跟我学机器视觉-HALCON学习例程中文详解-FUZZY检测用于开关引脚测量

    跟我学机器视觉-HALCON学习例程中文详解-FUZZY检测用于开关引脚测量 * This example program demonstrates the basic usage of a fuzz ...

  2. 跟我学机器视觉-HALCON学习例程中文详解-测量圆环脚宽间距

    跟我学机器视觉-HALCON学习例程中文详解-测量圆环脚宽间距 This example program demonstrates the basic usage of a circular meas ...

  3. 跟我学机器视觉-HALCON学习例程中文详解-开关引脚测量

    跟我学机器视觉-HALCON学习例程中文详解-开关引脚测量 This example program demonstrates the basic usage of a measure object. ...

  4. Hadoop深入学习:MapTask详解

    转自:http://flyingdutchman.iteye.com/blog/1878775#bc2337280 Hadoop深入学习:MapTask详解 博客分类: Hadoop MapTask执 ...

  5. Flink 从 0 到 1 学习 —— Flink 配置文件详解

    前面文章我们已经知道 Flink 是什么东西了,安装好 Flink 后,我们再来看下安装路径下的配置文件吧. 安装目录下主要有 flink-conf.yaml 配置.日志的配置文件.zk 配置.Fli ...

  6. iOS学习之UINavigationController详解与使用(一)添加UIBarButtonItem

    http://blog.csdn.net/totogo2010/article/details/7681879 1.UINavigationController导航控制器如何使用 UINavigati ...

  7. [转]iOS学习之UINavigationController详解与使用(三)ToolBar

    转载地址:http://blog.csdn.net/totogo2010/article/details/7682641 iOS学习之UINavigationController详解与使用(二)页面切 ...

  8. [转]iOS学习之UINavigationController详解与使用(二)页面切换和segmentedController

    转载地址:http://blog.csdn.net/totogo2010/article/details/7682433 iOS学习之UINavigationController详解与使用(一)添加U ...

  9. 各大公司广泛使用的在线学习算法FTRL详解

    各大公司广泛使用的在线学习算法FTRL详解 现在做在线学习和CTR常常会用到逻辑回归( Logistic Regression),而传统的批量(batch)算法无法有效地处理超大规模的数据集和在线数据 ...

  10. 跟我学机器视觉-HALCON学习例程中文详解-QQ摄像头读取条码

    跟我学机器视觉-HALCON学习例程中文详解-QQ摄像头读取条码 第一步:插入QQ摄像头,安装好驱动(有的可能免驱动) 第二步:打开HDevelop,点击助手-打开新的Image Acquisitio ...

随机推荐

  1. Java中的装箱拆箱

    一)  装箱与拆箱 Java中有概念是一切皆对象,因为所有的类都默认继承自Object.但是,对于数据类型是个例外,如short,int,long,float,double, byte,char,bo ...

  2. java使用thrift

    maven项目添加依赖: <dependency> <groupId>org.apache.thrift</groupId> <artifactId>l ...

  3. IOS开发-phonegap及免证书及真机调试

    回头补记(Last edited at 2015.5.24). 第一步:建立项目 参见:Xcode5 + phoneGap2.9搭建ios开发环境 下载phonegap2.9.1,解压. 命令行,进入 ...

  4. 1307: City Tour

    1307: City Tour Time Limit: 1 Sec  Memory Limit: 128 MB [Submit][Status][Web Board] Description Alic ...

  5. OSGI.NET 插件启动方法

    在使用OSGI.NET框架来开发插件过程中,有时为了测试一个插件,或运行一个插件,需要启动主个插件,如果没有主窗口程序,那么该 如何启动一个插件,而不是再开发一个主窗口程序(那样是不是太麻烦,仅仅是为 ...

  6. 图的最短路算法 Bellman-Ford

    BF求图的最短路径的时间复杂度是O(MN),这样的时间复杂度并不比迪杰斯特拉算法好,但是BF算法支持图中存在负权的情况,但图中不能存在负圈,因为如果存在负圈,最短路是不存在的,因此BF算法的另一个重要 ...

  7. 华为OJ平台——整数的二进制中1的个数

    题目描述: 输入一个整数,求该整数的二进制表达中有多少个1.例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 思路: 这是一道很基本的考查位运算的面试题.包括微软在内的很多公司都曾采用 ...

  8. dll延迟加载

    用于隐式链接选项, 这样设置后在exe调用dll的函数才会加载dll,调用DLL_PROCESS_ATTACH.否则隐式链接直接会在exe启动时加载dll

  9. java中List Set Map使用

    @Test         public void run()        {                              ArrayList<String> list= ...

  10. python列表的常用操作方法

    主要介绍了Python中列表(List)的详解操作方法,包含创建.访问.更新.删除.其它操作等,需要的朋友可以参考下. 1.创建列表.只要把逗号分隔的不同的数据项使用方括号括起来即可 List = [ ...