perform_nowだとquery cacheが効かない?が、perform_laterだと効く
会社のslackの分報でrailsでsqlの結果をメモ化するにはどんな方法がいいんだ?
みたいなことを呟いたら、そもそもquery cacheが効くんじゃない?と言われましたが、
https://railsguides.jp/caching_with_rails.html#sql%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5
railsガイドでも↑のような書き方で、Active Jobには関係ないのかとずっと思ってました。
ただ、perform_laterだとquery cacheが効くという助言をいただいたので、検証して見ることに。
https://github.com/na8esin/rails7_mysql_docker/tree/21630b376013d0059daab1553760bb15f4eb636b
rails7 + aws-sdk-rails + mysql8 + localstack(sqs)の組み合わせです。
まず、jobのコードはこんな感じです
class BookJob < ApplicationJob queue_as :default def perform Book.find(1) Book.find(1) end end
perform_nowの結果です。
irb(main):002:0> BookJob.perform_now Performing BookJob (Job ID: de1e614d-42d8-4568-9766-f38218dfac4c) from AmazonSqs(default) enqueued at Book Load (3.9ms) SELECT `books`.* FROM `books` WHERE `books`.`id` = 1 LIMIT 1 Book Load (0.2ms) SELECT `books`.* FROM `books` WHERE `books`.`id` = 1 LIMIT 1 Performed BookJob (Job ID: de1e614d-42d8-4568-9766-f38218dfac4c) from AmazonSqs(default) in 81.96ms => #<Book:0x0000ffff83294108 id: 1, status: "available", created_at: Tue, 12 Sep 2023 10:05:54.264743000 UTC +00:00, updated_at: Tue, 12 Sep 2023 10:05:54.264743000 UTC +00:00>
ログにはCACHEとはでてないですね。でも2回目は3.7msも早い。本当に効いてないのか? ちょっと不安になったので、タイトルにも?がついてます。
次は perform_laterです。
まずは、rails cでBookJob.perform_later
を実行しておきます。
そのあと、rails cを抜けてから、RAILS_ENV=development bundle exec aws_sqs_active_job --queue default
を実行して、少々待つと下記のようなログがファイルに出力されます
[ActiveJob] [BookJob] [b8cd5b55-1d44-420d-bfe5-89b7c67be8d5] Performing BookJob (Job ID: b8cd5b55-1d44-420d-bfe5-89b7c67be8d5) from AmazonSqs(default) enqueued at 2023-09-14T10:28:21Z [ActiveJob] [BookJob] [b8cd5b55-1d44-420d-bfe5-89b7c67be8d5] [1m[36mBook Load (0.1ms)[0m [1m[34mSELECT `books`.* FROM `books` WHERE `books`.`id` = 1 LIMIT 1[0m [ActiveJob] [BookJob] [b8cd5b55-1d44-420d-bfe5-89b7c67be8d5] ↳ app/jobs/book_job.rb:8:in `perform' [ActiveJob] [BookJob] [b8cd5b55-1d44-420d-bfe5-89b7c67be8d5] [1m[36mCACHE Book Load (0.0ms)[0m [1m[34mSELECT `books`.* FROM `books` WHERE `books`.`id` = 1 LIMIT 1[0m [ActiveJob] [BookJob] [b8cd5b55-1d44-420d-bfe5-89b7c67be8d5] ↳ app/jobs/book_job.rb:10:in `perform' [ActiveJob] [BookJob] [b8cd5b55-1d44-420d-bfe5-89b7c67be8d5] Performed BookJob (Job ID: b8cd5b55-1d44-420d-bfe5-89b7c67be8d5) from AmazonSqs(default) in 20.99ms [Aws::SQS::Client 200 0.009193 0 retries] delete_message(queue_url:"http://localstack:4566/000000000000/my-queue",receipt_handle:"MWM5Mzg3MjktZmM2Yy00YzcyLTgxMDktZWMwMDNlZGFmMTUwIGFybjphd3M6c3FzOmFwLW5vcnRoZWFzdC0xOjAwMDAwMDAwMDAwMDpteS1xdWV1ZSBhNGRlMWQyMy1lOWZiLTQzZWUtYjcxYS01MzE1Nzc0OGRjMTkgMTY5NDY4NzMyNS44OTY2MTA1")
CACHEと出てますね。
ただ、この例だと、ログにCACHEと出ているだけなのか、本当にCACHEが効いてるのかはわかりづらいですね。
時間がある時にrails本体のソースを読んでみたいと思います。
RemoteConfig使ってみる(swift)
アプリには欠かせないapi呼び出しですが、urlのドメインだけを変えたい場合があると思います。
まずは、iosアプリとして、サンプルを作ってみました。
https://github.com/na8esin/ios-remote-config
AppDelegateでRemoteConfigのsetupを行うサンプルになってます。
また、structにURLなどの定数を押し込めてるプロジェクトもよくあると思いますので、 そこで、RemoteConfigを呼び出すようにしてみました。
RemoteConfigで取得した値をUIに反映させるのは、とりあえずボタンで行っています。
本当は、ListenerがRemoteConfigの更新を検知したタイミングで、UIを更新したり、 splashの画面に遷移したいところです。
FirebaseApp.initializeApp不要らしい
Androidのプロジェクトで、Remote Configの導入を検討しており、まずは下記のquickstartをダウンロードして、実行してみることに
https://github.com/firebase/quickstart-android/tree/master/config
java.lang.RuntimeException: Unable to start activity ComponentInfo{ta.watanabe.practice/com.google.firebase.quickstart.config.java.MainActivity}: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process ta.watanabe.practice. Make sure to call FirebaseApp.initializeApp(Context) first.
FirebaseApp.initializeApp(Context)
かあ、そういえば必要だったなと思って、追記してみるも同じ結果。。。
そして下記に辿り着きました。
https://github.com/firebase/firebase-android-sdk/issues/4693#issuecomment-1674688652
Added apply plugin: 'com.google.gms.google-services' to app/build.gradle. Also added classpath 'com.google.gms:google-services:4.3.4' to build.gradle
上記の通りに追記すると動くようになりました。
AWS Lambdaをnodejs18.xで作成して、コードを管理しようとした時にハマったこと
まず、Serverless Frameworkでコード管理をしようと思いました。
nodejs18.xを選択すると拡張子がデフォルトで.mjsになっていますが、まだその拡張子に対応してないようでした。
https://github.com/serverless/serverless/pull/11366
拡張子を.jsにしてES モジュールとして扱う方法もありますが、
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-nodejs.html
他の人が見た時にわかりづらいと思ったので、Serverless Framework自体の利用を一旦、諦めました。
そうなるとTerraformで管理しようかと思って、tfファイルをある程度書いて、planを実行したところ下記のエラーに遭遇しました。
https://github.com/hashicorp/terraform-provider-aws/issues/27878
こちらは、すでに対応されていたので、providerのバージョンを上げれば解決しました。
Alpine Linuxでもaws cli v2がapk addでインストールできる
普通にpackagesに載ってる
https://pkgs.alpinelinux.org/packages?name=aws-cli&branch=edge&repo=&arch=&maintainer=
↓でも言及されている
https://github.com/aws/aws-cli/issues/4971#issuecomment-1631160032
dockerで試してみた
aws cliはterragruntと一緒に使いたくなる場合が多いと思うので、alpine/terragruntのimageで試してみました(m1 macです)。
とりあえずは、問題なさそう。
Android, iOSのアプリで使用しているTwitterのAPIがついに使えなくなった
仕事でメンテナンスしているアプリのTwitter連携の機能が突然使えなくなったので、調べました。
世間で使えなくなったと言われているよりタイムラグがあったのと、Android, iOSで使えなくなった日がそれぞれ違く、数日ラグがありました。
多分、Android, iOSで使ってるConsumer Keyがそれぞれ違うからだと思われます。
動作確認にはtwurlが一番簡単そうだなと思って、まずはインストールしました。
Twurlを使用する | Docs | Twitter Developer Platform
そして上の記事通りauthorizeします。
そして、該当のapiを実行。
$ twurl /1.1/users/show.json {"errors":[{"message":"You currently have access to a subset of Twitter API v2 endpoints and limited v1.1 endpoints (e.g. media post, oauth) only. If you need access to this endpoint, you may need a different access level. You can learn more here: https://developer.twitter.com/en/portal/product","code":453}]}
同じエラーに出会した人もいるようです。
v2を使えるようにすればいいんですが、アプリが2つ(Android, iOS?)あると、有料だそうなので、まだどうするかの結論が出ていないです。
content_tag(divタグ)になったりlink_toになったりするヘルパー
詳しい要件は忘れてしまいましたが、htmlタグの要素だけ違くて、他はほぼ同じみたいなことをすることがあります。
その場合もerbで分岐処理を書かずに、blockを使ってhelperに書くとスッキリする気がしました。
module SomeHelper def content_tag_or_link_to(path, class:, is_content_tag: false, &block) if is_content_tag content_tag :div, class:, &block else link_to path, class:, &block end end end
<%= content_tag_or_link_to some_path, class: "btn", is_content_tag: @is_content_tag do %> <div class="label">cssによりボタンの見た目をしています</div> <% end %>