iOSアプリの行動ログをTreasure Dataへ登録しようとしたらデータが重複してはまった話
TDにiOS向けのSDK(td-ios-sdk)で、起動時のログを登録しようとしたら、サーバサイドに登録したデータが重複してたよという話題です。(多分仕様です。)
やりたかったことの概要
アプリの起動時にいろいろな箇所でaddEvent()をやって、サーバにuploadしたかどうかは管理したくないので、addEvent()した直後にuploadEvents()を都度実行するといったことをやってみました。
コードイメージ
TreasureData.sharedInstance().addEvent(["msg":"first"], database: "test_app", table: "test_table")
TreasureData.sharedInstance().uploadEvents()
TreasureData.sharedInstance().addEvent(["msg":"second"], database: "test_app", table: "test_table")
TreasureData.sharedInstance().uploadEvents()
結果
firstとsecondのレコードがそれぞれ2件作られました。
重複に関する調査
その1
TDサイトに最後に登録された10分間にUUIDが重複していたら削除すると書かれています。
その2
サーバー側でイベントの重複排除を行っているためアップロードが複数回行われてもデータの重複を防止(現在、1日間の重複排除を実施)
td-ios-sdk のコミッタの方の記事でサーバーサイドで重複に対する考慮されているとありました。
SDKでレコードを追加すると、レコード毎に値が異なるuuidカラムが暗黙のうちに追加されていて、enableAutoAppendRecordUUID()との違いがよくわっていなかったのですが、uuidカラムを使って重複削除する仕組みのようです。ただ、実験した環境だと動いていないようでした。
回避をこころみた
やってみたこと
uploadEventsメソッドにはコールバックを受け付けるバリエーションがあります。これを使って、uploadEventsを直列化すれば重複を回避できそうです。
TreasureData.sharedInstance().uploadEventsWithCallback(
{
//成功した場合
},
onError: {errCode,errMsg in
//失敗した場合
}
)
//dispatch_sync()とかdispatch_semaphore_waitとかで直列に処理する
結果
Request data is empty とログがでて、直列化の途中で詰まりました。内部のKeenClientクラスで、アップロードするデータが無い場合は、成功のブロックも、失敗のブロックも呼ばない仕様のようです。
今回のまとめ
さがせば書いてあるのかもしれませんが、公式のドキュメントとgithubのプロジェクトを1日くらい眺めていましたが、特にこれ以上の情報は見つけられませんでした。サーバに登録されたレコードには、timeカラムが自動的に付与されて処理時間が記録されるのですが、ミリ秒以下の時間は丸められています。ディフォルトだと秒単位でレコードを記録をする仕組みなので、1秒間に何度もイベントを記録するといった用途はそもそも向いていないのかもしれません。
Author And Source
この問題について(iOSアプリの行動ログをTreasure Dataへ登録しようとしたらデータが重複してはまった話), 我々は、より多くの情報をここで見つけました https://qiita.com/grachro/items/dce05da7440f453e7057著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .