Skip to content

Instantly share code, notes, and snippets.

@hassaku63
Last active July 7, 2020 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hassaku63/ffdfa6f61ff5a92958b096721a3c21af to your computer and use it in GitHub Desktop.
Save hassaku63/ffdfa6f61ff5a92958b096721a3c21af to your computer and use it in GitHub Desktop.
import functools
class Hook(object):
def init(self, event, context):
print(f'hook init: {event} {context}')
def before(self, event, context, record):
print(f'hook before: {event} {context} {record}')
def after(self, event, context, handler_return):
print(f'hook after: {event} {context} {handler_return}')
def exit(self, event, context):
print(f'hook exit: {event} {context}')
def handler(hook: Hook):
"""This function is a fake implementation that assumes Jefffy handler (e.g SqsHandlerMixin.sqs)"""
def wrap_handler(func):
@functools.wraps(func)
def wrapper(event, context):
hook.init(event, context)
for record in event.get('Records', []):
hook.before(event, context, record)
ret = func(record, context)
hook.after(event, context, ret)
hook.exit(event, context)
return wrapper
return wrap_handler
@handler(Hook())
def main(event, context):
print(f'main {event}')
return f'main({event})'
if __name__ == '__main__':
main({
'Records': [1,2,3]
}, {})
@hassaku63
Copy link
Author

hassaku63 commented Jul 7, 2020

batch writer 用のカスタムHookを作るとしたらこうなる?(TableクラスはひとまずMockで代用)

class DynamodbBatchWriterHook(object):
    def __init__(self, table_name: str):
        self.table_name = table_name
        self.table = None
        self.batch_writer = None

    def init(self, event, context):
        self.table = Mock(name='Table mock')
        self.batch_writer = self.table.batch_writer()
    
    def before(self, event, context, record):
        pass

    def after(self, event, context, handler_return):
        self.batch_writer.put_item(Key=handler_return)

    def exit(self, event, context):
        self.batch_writer.__exit__()

この実装ではPutItemしかできない前提になる点と、コンテキストマネージャとして意図されているクラスを無理やり適合させる感じになるのでいかにも苦しい感じはする....。
(最後の __exit__ も、おそらくコンテキストマネージャに必要な引数が入っていないので多分このままでは動かないはず)

@hassaku63
Copy link
Author

hassaku63 commented Jul 7, 2020

この手のフックインタフェース、おそらくデコレータのようなミドルウェア的ポジションより一歩ユーザー寄りな目線でカスタマイズのポイントを提供する手段として使用するべきで、おそらく Batch write のユースケースとはちょっとモチベーションの方向性が違うのでは、という気持ち。お仕着せのフックを提供する形になるのはどうも根本的なアプローチがずれているような。

Hookのアイデア自体は、あっても良いもののようにも思う(今のところ、適切なユースケースは思いつかないけど)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment