GAE Python上的Mapreduce-导致ReducePiline在finalize时发出回调?

GAE Python上的Mapreduce-导致ReducePiline在finalize时发出回调?,python,google-app-engine,mapreduce,Python,Google App Engine,Mapreduce,我希望在mapreduce作业完成后执行自定义回调函数 对于这个问题,我找到的唯一有用的参考资料是和一个相关的,但又似乎过时了 这两个源都假设我使用control.start\u map启动Mapreduce作业,并依赖于start\u map接受关键字参数Mapreduce\u参数,其中可以指定done\u回调参数来指定完成时应调用的url。但是,我使用的是另一种方法(afaik是最近的首选方法),其中自定义管道的run方法生成Mapreduce管道: yield mapreduce_pipe

我希望在mapreduce作业完成后执行自定义回调函数

对于这个问题,我找到的唯一有用的参考资料是和一个相关的,但又似乎过时了

这两个源都假设我使用
control.start\u map
启动Mapreduce作业,并依赖于
start\u map
接受关键字参数
Mapreduce\u参数
,其中可以指定
done\u回调
参数来指定完成时应调用的url。但是,我使用的是另一种方法(afaik是最近的首选方法),其中自定义管道的
run
方法生成Mapreduce管道:

yield mapreduce_pipeline.MapreducePipeline(
    "word_count",
    "main.word_count_map",
    "main.word_count_reduce",
    "mapreduce.input_readers.BlobstoreZipInputReader",
    "mapreduce.output_writers.BlobstoreOutputWriter",
    mapper_params={
        "blob_key": blobkey,
    },
    reducer_params={
        "mime_type": "text/plain",
    },
    shards=16)
MapReduceEpiLine的签名不允许使用
mapreduce\u参数
参数。在源代码中,我只能在
mapper\u pipeline.mapperppipeline.run
中看到对回调的引用,但它似乎只在内部使用

那么,有没有办法把回调参数放在里面


如果没有,是否有人对在何处以及如何扩展库以提供这样的功能有好的想法?

对于这个问题,至少一个投资不多的解决方法是简单地生成另一个执行所需后处理的Map/Mapreduce管道

例如:


该解决方案没有访问Mapreduce状态的权限,我认为可以通过某种方式从管道ID检索到Mapreduce状态,但我还不清楚如何检索。因此,您必须设置另一个标志/memcache/ds条目来检查管道是否成功完成(如果这与后处理相关)。

我将Mapreduce管道范例设置为如下所示:

class MRRecalculateSupportsPipeline(base_handler.PipelineBase):

    def run(self, user_key):
        # ...
        yield mapreduce_pipeline.MapreducePipeline('user_recalculate_supports',
                'myapp.mapreduces.user_recalculate_supports_map',
                'myapp.mapreduces.user_recalculate_supports_reduce',
                'mapreduce.input_readers.DatastoreInputReader', output_writer_spec=None,
                mapper_params={"""..."""})
如果您希望捕获此管道的完成情况,您有两种选择

A) 使用pipeline.After在MR管道完成后运行完成管道

        pipe_future = yield mapreduce_pipeline.MapreducePipeline('user_recalculate_supports',
                'myapp.mapreduces.user_recalculate_supports_map',
                'myapp.mapreduces.user_recalculate_supports_reduce',
                'mapreduce.input_readers.DatastoreInputReader', output_writer_spec=None,
                mapper_params={"""..."""})
        with pipeline.After(pipe_future):
            yield CalcCompletePipeline(...)  # this could be a mapreduce pipeline, or any pipeline using the same base_handler.PipelineBase parent class.
B) 使用顶级管道的
最终确定的
方法来处理完成。就我个人而言,我坚持使用选项A,因为您可以在
/\u ah/*/status?root=
视图中跟踪路径

class EmailNewReleasePipeline(base_handler.PipelineBase):
    """Email followers about a new release"""
    # TODO: product_key is the name of the parameter, but it's built for albums ...

    def run(self, product_key, testing=False):
            # Send those emails ...
            yield mapreduce_pipeline.MapreducePipeline(...)

    def finalized(self):
        """Save product as launched"""
        ...
        product.launched = True
        product.put()

以下是网站上的文档。

使用memcache来实现这一目的令人担忧-无法保证结果可用。不过,我同意另辟管道的想法。上面肯定缺少的一件事是与
pipeline.After一起使用((yield mapreduce_pipeline.MapReducePipeline…
你知道pipeline.After到底是什么,或者为什么有必要这么做吗?根据我的经验,简单地生成后处理管道将在主管道完成后执行其代码。这也是检索中输出文件blobkey的方式,所以我对它一无所知。pipeline.After需要确保生成的管道的正确执行顺序。到目前为止,我最喜欢的管道功能之一,在文档中:
class EmailNewReleasePipeline(base_handler.PipelineBase):
    """Email followers about a new release"""
    # TODO: product_key is the name of the parameter, but it's built for albums ...

    def run(self, product_key, testing=False):
            # Send those emails ...
            yield mapreduce_pipeline.MapreducePipeline(...)

    def finalized(self):
        """Save product as launched"""
        ...
        product.launched = True
        product.put()