GW期間中にAmplify SNS Workshopをやってみた。とても面白い内容だったが、ちょっとおかしな挙動をする部分もあった。
本ワークショップのゴール :: Amplify SNS Workshop
ここの図にある通り、AppSync / Cognito / Lambda / DynamoDB等々様々なAWSのサービスをAmplify CLIを使ってTwitterっぽいものを作るチュートリアル。最終的にはgithubにpushするとCIでE2Eテストが動いてその動画をAWSコンソールからダウンロードできる。すごい。 CognitoやLambdaは単体では使ったことがあるので、これ単体でもいろいろノウハウがあって動かすの大変なのに、うまくインテグレートされてるなあと感心した。
ボリュームとしては多くはない。ただデプロイするのに結構時間がかかるので、その間に別のこと始めちゃったりしてだらだらやっていたら3日くらいかかりました。
Timeline上のPostが重複する
Timelineを表示しながらPostすると、Postが重複してしまうという現象が発生した。
PostはLambdaによって
- PostTableにSaveされる
- 自分と自分のFollowerのTimelineに保存される
この2の処理が意図せず複数回呼び出されているようだ。ただし保存している内容は同じなので結果的には上書きされているだけなんだけど、クライアント側ではこれをsubscribeしてTimelineを表示しているため重複して表示してしまう。その後リロードするとTimelineを読み直すので重複は解消される。
CloudWatchでLambdaのログを見るとこのようになっていた。
2020-05-10T06:27:49.322Z d130970d-d15d-496c-9344-42c58f5c40ad INFO [ { followerId: 'iakio' }, { followerId: 'iakio' }, { followerId: 'iakio' }, { followerId: 'iakio' } ]
followerに自分自身が複数入っている。しかしDynamoDBのFollowRelationshipには何も入っていない。どうもLambdaの中で何かが起きているようだ。
const listFollowRelationshipsResult = await graphqlClient.query({ query: gql(listFollowRelationships), fetchPolicy: 'network-only', variables: queryInput, }); console.log(listFollowRelationshipsResult); const followers = listFollowRelationshipsResult.data.listFollowRelationships.items; console.log(followers); //post to timeline followers.push({ followerId: post.owner, }) const results = await Promise.all(followers.map((follower)=> createTimelineForAUser({follower: follower, post: post})));
Timeline機能: @function :: Amplify SNS Workshop
LabmdaやAppSyncについて詳しくないのだが、どうも
- graphqlClient.query()の戻り値の中のfollwersにpushで破壊的変更をしたら、次にgraphqlClient.queryした時の結果に影響する?
- しかもそれが次のLamdaの呼び出しにも影響している? graphqlClientがglobalスコープなんだけど、Lambdaでglobalスコープってどうなるんだっけ
という感じがしている。ちなみにpushをやめたら現象は発生しなくなった。
const followersAndI = followers.concat({ followerId: post.owner, }); const results = await Promise.all(followersAndI.map((follower)=> createTimelineForAUser({follower: follower, post: post})));