Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

events.Records を配列形式のまま扱えるデコレータの追加 #1

Open
hassaku63 opened this issue Jul 1, 2020 · 6 comments
Labels
enhancement New feature or request

Comments

@hassaku63
Copy link

hassaku63 commented Jul 1, 2020

Kinesis/SQS など、配列形式の Records を受け取るイベントの場合、それらの各イベントの処理結果を DynamoDB に PUT したいケースがあります。

そのような場合の書き込みには BatchWriter を利用するので、 Records をそのまま扱える方が都合が良いケースがあるように考えます。

  • 今ある SQS ハンドラ jeffy.handlers.sqsjeffy.handlers.sqs_each にリネーム
  • Records を配列のまま受け取るハンドラ jeffy.handlers.sqs として提供

または

  • Records を配列のまま受け取るハンドラを追加 (e.g jeffy.handlers.sqs_batch / jeffy.handlers.sqs_records
    )

のように、受け取れるイベントの単位は配列/各要素のどちらも使えるようにするのはいかがでしょうか

Related discussion: serverless-operations/jeffy#25

@horike37
Copy link
Contributor

horike37 commented Jul 1, 2020

@hassaku63
アイデアありがとうございます!確かに今のデコレータだとBatchWriter使いたい場合に難しくなるので、専用のデコレータはほしいですね。

Records を配列のまま受け取るハンドラを追加 (e.g jeffy.handlers.sqs_batch / jeffy.handlers.sqs_records)

こちらが良いかなと思います。既存のハンドラ名を変えてしまうと後方互換性が失われてしまうので、新しいのを追加するほうが良いかなと。

@horike37
Copy link
Contributor

horike37 commented Jul 1, 2020

受け取れるイベントの単位は配列/各要素のどちらも使えるようにするのはいかがでしょうか

そうですね!良さそうです。まずは実装にあたって仕様を決めないとなので、
具体的な仕様に落とし込んでみますかねー。この辺イメージあります?

@marcy-terui
Copy link

Recordsを複数そのまま扱うdecoratorはそれはそれであって良い思うんですが、メッセージのデコードをしなくてはいけない関係で一回Recordsを展開しないといけなくて、そうすると2回ループ回すことになるから非効率で、一つずつ処理した結果を貯めて、全部終わってからそれを使った後処理を書けるようにしたいなって気持ちもあるんですよねー

@hassaku63
Copy link
Author

hassaku63 commented Jul 3, 2020

具体的な仕様のイメージは現時点持っていないですねー。

@marcy-terui さんが言うように、デコード絡めると確かにデコレータ側で1ループ増えるのはあんまりイケてない感じがしますし、単にRecordsを受け取るよりは今の形を代えず後処理として何かしら記述できるように方がよいのかも、という感じはしました。

後処理を追加できる、って考え方に立つとハンドラ内でコンテキストマネージャあるいはコールバック関数をユーザー定義できる感じが利用者的には良いのかなと考え始めています(具体的なインタフェースはまだ no idea ですが)。

コールバックの場合は各レコードの処理が終わった後で発動するもの、もしくは各アイテムの処理を終えたタイミングで挟めると良いのかなと。今回 issue で挙げたユースケースで言うと後者ですかね。

コールバックだと Table のコンテキストマネージャをどう使うか悩ましいですね。週末に考えてみます

@hassaku63
Copy link
Author

hassaku63 commented Jul 7, 2020

考えてはみたものの、あまり良いアイデアが浮かばないですね、、

boto3 から呼び出す主要サービスで batch write 系の操作を実装するものは SQS, Kinesis, DynamoDB などがありますが、このうち DynamoDB BatchWriter だけがコンテキストマネージャーによる実装になっているので、そのへんも少々ネックに感じています。

コールバック系のインタフェースを追加するにしても、sdk (boto3) が必要になるのはデコレータ通したハンドラが実行されるタイミングですし。ユーザーがjeffyを用いた普段の実装で意識する部分(つまりデコレートしたハンドラ内)では既に dynamodbクライアントを初期化したいタイミングを逃している感じもしますね(そしてflushするべきタイミングもユーザーが意識する領域の外にありますし)。

hook的なインタフェースを持つ基底クラスを作って汎用的に作れないか?というのが今検討している方針になります。hookクラスを渡す口は既存のハンドラデコレータくらいだろうなと思っています。ストレートに理解できる仕様になるかどうか?という疑問はありますが。。。現状具体性のある提案はできませんが、とりあえず今考えている内容としてポストしておくことにします。

@hassaku63
Copy link
Author

hassaku63 commented Jul 7, 2020

仮にhookで行く場合のラフな実装イメージを書いてみました。

https://gist.github.com/hassaku63/ffdfa6f61ff5a92958b096721a3c21af

おおよそ上のgistのような実装イメージになるんじゃないかと思いますが、これだと DynamoDB への書き込みをやる場合にユーザーが独自クラスをオーバーライドしなくてはならないので、あまりイケてないなという風にも感じます。BatchWriterとHookの噛み合わせも悪そうです。
※フックのライフサイクルでインタフェースがばらつく点も個人的にはあまり好みでないですね...。このへんはもっと良いインタフェースが思いつけば良いのですが、今はちょっと良案がありません

...となると、Recordsを配列のまま扱う別のデコレータがいた方が全体的な仕様としては見通しがよいのではないか?とも考えます。Encoderに関しては、(無駄なオーバーヘッドが生じますが)NoneEncoderのようなas-isの値しか返さない空のEncoderを作れば少なくとも今の仕様に対する影響は小さいのではないかなと。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants