Implementing Google BigQuery REST API (v2) jobs.query

これは はてなエンジニア Advent Calendar 2024 25日目の記事です。

github.com

Google BigQuery REST API (v2)のjobs.query を実装した Perl モジュールを作りました。

おすすめポイント

  • 列の値をフラットな hashref へ変換します
    • ->{f}->[0]->{v} みたいな値の探り方をしなくていいので便利です
    • なぜこういうデータ構造になっているのか全然わからない
  • 列の値のデータ型を JSON Schema で定義できるようになっています
    • データ入出力の境界には型があると安心です

やったこと

MinillaPerlモジュールの雛形を作るだけでした。簡単。

モジュールを作ろうと思った理由

Google::BigQueryDiscovery document という仕組みを使っていて、リクエスト先のURLを実行時に組み立てるようになっています。

しかし、いつからか Discovery document の返り値の path 要素に含まれるパス変数の形式が変化してしまい、動かなくなってしまっていました。

  • 期待値 projects/{projectId}/queries
  • 実際の値 projects/{+projectId}/queries
    •   "query": {
          "description": "Runs a BigQuery SQL query synchronously and returns query results if the query completes within a specified timeout.",
          "flatPath": "projects/{projectsId}/queries",
          "httpMethod": "POST",
          "id": "bigquery.jobs.query",
          "parameterOrder": [
            "projectId"
          ],
          "parameters": {
            "projectId": {
              "description": "Required. Project ID of the query request.",
              "location": "path",
              "pattern": "^[^/]+$",
              "required": true,
              "type": "string"
            }
          },
          "path": "projects/{+projectId}/queries",
          "request": {
            "$ref": "QueryRequest"
          },
          "response": {
            "$ref": "QueryResponse"
          },
          "scopes": [
            "https://www.googleapis.com/auth/bigquery",
            "https://www.googleapis.com/auth/cloud-platform",
            "https://www.googleapis.com/auth/cloud-platform.read-only"
          ]
        }
      

やらなかったこと

CPANへの登録

perlnewmod - 新しいモジュールを配布するには - perldoc.jp を読んで片手間ではやりきれんな、と思ってやめました。

Google::BigQuery に変更を提案

10年前に作られたモジュールで、GitHub リポジトリも消えているので、これ以上時間かけてもな、と思ってやめました。

明日の担当は id:k1s1eee さんです。

主体や目的を具体的に示す+結果をどう扱うかを示す

LLMは最大公約数的な答えを返してくれるので便利だな。 主体や目的を具体的に示すことは意識しているけど、結果をどう扱うかも示すようにしよう。

問いかけ

「コマンドを叩く」「コマンドを打つ」「APIに投げる」「 APIを叩く」「レビュー依頼を投げる」など、責任を押し付けるような言葉使いを憂いているので、どうすれば改善できるか建設的な意見を1000文字以内でまとめて欲しい。

Geminiの答え

責任転嫁を連想させる言葉遣いの改善策

「コマンドを叩く」「APIに投げる」といった表現は、まるでコンピュータに仕事を丸投げしているかのような印象を与え、責任感の欠如や、他者への丸投げを連想させる可能性があります。これらの言葉遣いを改善し、より建設的なコミュニケーションを促進するためには、以下の点に留意することが重要です。

1. 行動主体を明確にする

  • 「私が」コマンドを実行する
  • 「私が」APIを呼び出す
  • 「私が」レビュー依頼を行う このように、主語を明確にすることで、自分が主体的に行動していることを示し、責任感の有無を明確にします。

2. 行為の内容を具体的に説明する

  • 「コマンドを実行して、~という処理を行う」
  • APIを呼び出し、~というデータを取得する」
  • 「レビュー依頼を行い、~という点について確認をお願いする」

単に「コマンドを叩く」と言うよりも、具体的な処理内容を説明することで、何をしているのかを周りに理解してもらいやすくなります。

3. 相手への配慮を示す言葉を選ぶ

  • 「ご協力をお願いして、~を検証していただきたく」
  • 「~について、ご意見を伺えれば幸いです」

一方的な指示ではなく、相手への配慮を示す言葉を選ぶことで、共同で作業を進めるという意識を醸成します。

4. 結果に対する責任を持つことを示す言葉を選ぶ

  • 「この処理を実行した結果、~ということが確認できました」
  • 「このAPIの呼び出しによって、~というデータを取得し、~という結論に至りました」

結果に対する責任を持つことを示す言葉を選ぶことで、単に作業を行っただけでなく、その結果について深く考えていることを示します。

5. 問題発生時の対応について言及する

  • 「もしエラーが発生した場合には、~という対処を行います」
  • 「レビューの結果、修正が必要な箇所が見つかった場合は、~という対応を行います」

問題が発生した場合の対応について言及することで、責任感を持っていることを示し、安心感を与えることができます。

その他

  • 多様な表現を使う: 同じ言葉の繰り返しを避けることで、表現に変化を持たせ、単調さを解消します。
  • 状況に合わせて言葉を選ぶ: 状況や相手に合わせて、適切な言葉を選ぶことが重要です。
  • チームで共通の言葉遣いを決める: チーム内で共通の言葉遣いを決めることで、コミュニケーションの円滑化に繋がります。

これらの提案を参考に、状況に合わせて言葉を選ぶことで、より建設的なコミュニケーションを促進し、チーム全体の士気を高めることに繋がります。

まとめ

責任転嫁を連想させる言葉遣いを改善するためには、行動主体を明確にし、行為の内容を具体的に説明する、相手への配慮を示す言葉を選ぶ、結果に対する責任を持つことを示す言葉を選ぶ、問題発生時の対応について言及するなど、様々な工夫が考えられます。これらの提案を参考に、より良いコミュニケーションを目指しましょう。

ポイント

  • 主語を明確にする
  • 行為の内容を具体的に説明する
  • 相手への配慮を示す
  • 結果に対する責任を持つ
  • 問題発生時の対応について言及する

補足

上記はあくまで一般的な提案であり、具体的な改善策は、チームの状況や個人の性格などによって異なります。

さらに良い表現例

従来の表現 より良い表現
コマンドを叩く コマンドを実行する、スクリプトを実行する
APIに投げる APIを呼び出す、APIリクエストを送信する
レビュー依頼を投げる レビューをお願いする、レビュー依頼を送信する

その他

  • 「投げる」という表現は、物体を投げつけるイメージがあり、やや攻撃的な印象を与えます。
  • 「叩く」という表現は、力任せに行うイメージがあり、丁寧さを欠く場合があります。
  • 「依頼する」や「お願いする」といった言葉を使うことで、相手への敬意を示すことができます。

上記を参考に、状況に合わせて適切な言葉を選ぶようにしましょう。

ChatGPTの答え

現代の技術職や開発現場では、「コマンドを叩く」「APIを叩く」「レビュー依頼を投げる」といった表現が日常的に用いられます。しかし、これらの表現はそのまま受け取ると、曖昧さや責任を転嫁する意識が潜在的に含まれていると感じられる場合があります。そのため、より明確で責任を意識した言葉遣いに改善することが望ましいと考えられます。以下に具体的な改善策を提案します。

1. アクションの主体を明確にする

曖昧な表現はしばしば行為の主体を不明瞭にします。「コマンドを叩く」「APIを叩く」という言葉は単なる行為の発生を指しますが、「〇〇を実行する」「〇〇にリクエストを送信する」といった表現にすることで、何が行われているのかを具体的に説明できます。また、「レビュー依頼を投げる」という表現も、「〇〇さんにレビューを依頼する」と明確にすることで、依頼する人の名前を出し、責任の所在を明らかにすることができます。

2. 行動の目的を意識する

アクションの背景にある目的を言葉に含めると、表現の意味が具体化され、責任感が伴います。「APIに投げる」という表現を、「データを取得するためにAPIにリクエストを送る」とすることで、行動の目的が明確になります。目的を意識することで、行動の価値が共有され、他者にも正確に伝わります。

3. 曖昧な言葉を避ける

「叩く」「投げる」といった言葉は感覚的でカジュアルな印象を与えるため、状況によっては専門的な言語に置き換えるのが有効です。「コマンドを叩く」ではなく、「コマンドを実行する」「コマンドを入力する」と言い換えることで、具体性と共に責任が伝わります。チーム内のやりとりをフォーマルにする必要がある場合には特に有効です。

4. チーム文化の見直し

言葉遣いは文化や習慣から生まれるため、改善にはチーム全体での意識の共有が必要です。定期的に言葉遣いに関するワークショップを開くことで、より建設的で責任感のあるコミュニケーション方法を模索する場を設けるのも有効でしょう。また、コードレビューやフィードバックの場で、意識的に明確な言葉を使うことを推奨し、習慣化を目指します。

5. 誤解を防ぐ意識を持つ

相手に誤解を与えないことも大切です。「レビューを依頼する」という言葉は、「レビューの時間をお願いしている」という意識を伝えるために、「〇〇さんにレビューをお願いしてもよいでしょうか」といった丁寧な表現にすることが考えられます。これにより、相手の時間や負担に配慮する姿勢が伝わります。

このように、言葉を丁寧に選ぶことで責任感を伴ったコミュニケーションが可能になり、チーム全体の信頼感を高めることができます。

【未公開記事の発掘】AWS Lambda ファンクションのインスタンスをウォームアップ状態で維持したい

起動に時間のかかるファンクションで困っていたのかもしれない。


背景

  • HTTP リクエストを処理するだけの Lambda ファンクションがある
  • ほとんどリクエストがこないのでそのたびに新規作成してる
  • リクエストの送信元が設定している応答タイムアウト時間が短くて、エラーになりやすい

目的

  • リクエストの送信元でタイムアウトしないようにしたい
  • リクエストのたびに新規作成しないで済むよう Lambda ファンクションを WarmUp 状態で維持する
  • できるだけ費用がかからないようにする

世の中の知見

ソリューション

Lambda ファンクションのインスタンスVPC で実行するなら15分、そうでないなら5分くらいで廃棄されるようです。

廃棄までの時間内に新しいイベントが到着すれば、継続して動き続けるはず。

できるだけ費用がかからないように、という前提があっても、定期的にリクエストを送信する方法はいろいろ考えられます。

第7回 Data-Oriented Programming 読書会


参加者トピック

  • 引き続き chatGPT 話題
    • 最近は Edge で Bing AI を使うことが増えている
    • ライブラリの選定に使っている人がいたりする
  • ステージマネージャ は便利なのでお勧め
  • Anker が古くなったモバイルバッテリーを引き取るキャンペーンをしている

nextbook

ディスカッション

13.4 Multimethods with dynamic dispatch

  • 実行時のデータに基づいて呼び出す関数を決める仕組みのことだった
  • 汎用データ構造でも静的型付け言語と同じようなことができる、ということなのかな

13.5 Integrating multimethods in a production system

  • 普通はプレゼンテーションに近いところで書式を指定するものだけど、モデルのすぐそばで判断、加工しているのは不思議

13 Summary

14 Advanced data manipulation

14.1 Updating a value in a map with eloquence

  • データを取得して加工して設定するのではなく、データを加工する関数を渡すようにする

14.2 Manipulating nested data

  • flatMapflatten + map のどちらが分かりやすいか議論している

14.3 Using the best tool for the job

  • forEach を撲滅したい

14.4 Unwinding at ease

  • MongoDB の $unwind オペレータは便利

14 Summary

15 Debugging

15.1 Determinism in programming

  • いろんな層の言葉が乱用されているし、基本的な事実を新発見のように説明しているので、読んでいてつらい
  • 経験主義というやつだろうか

15.2 Reproducibility with numbers and strings

15.3 Reproducibility with any data

15.4 Unit tests

15.5 Dealing with external data sources

15 Summary

参考情報

第6回 Data-Oriented Programming 読書会


参加者トピック

  • chatGPT の話ばかりしてる
  • GitHub CopilotOSS メンテナ認定は雑すぎて助かる
  • GPU ボードのメモリは 16 GB ないと厳しい

ディスカッション

11.3 Representing a client request as a map

  • 最初から汎用的なAPIにするのは早すぎる最適化だと思う

11.4 Representing a server response as a map

  • properties にフィールド名を書かなくても required に書いただけでフィールドを生やすらしい

11.5 Passing information forward

特になし

11.6 Search result enrichment in action

特になし

11 Summary

特になし

Part 3. Maintainability

特になし

12 Advanced data validation

特になし

12.1 Function arguments validation

  • 保守を任されたシステムで、最初の仕事がデータの型付けだったら辛すぎる
  • JSON Schema に静的型付け言語と同じような表現力を求めている

12.2 Return value validation

特になし

12.3 Advanced data validation

  • LOCALE=C date の出力を見ると format="date" が受け入れてもらえる気がしない
  • 不安なので正規表現を書いてしまう、と思う

12.4 Automatic generation of data model diagrams

PlantText UML Editor

12.5 Automatic generation of schema-based unit tests

12.6 A new gift

  • JSON Schema はフィールドの値域が条件によって変わるようだと記述量が多くなりがちで困る

12 Summary

  • OpenAPI は JSON Schema のスーパーセットでありサブセットでもあるので OpenAPI を使っていくとよさそう

13 Polymorphism

13.1 The essence of polymorphism

13.2 Multimethods with single dispatch

13.3 Multimethods with multiple dispatch

PlayCode - Javascript Playground

参考情報

第5回 Data-Oriented Programming 読書会


参加者トピック

ディスカッション

9 Persistent data structures

9.1 The need for persistent data structures

https://lampwww.epfl.ch/papers/idealhashtrees.pdf

9.2 The efficiency of persistent data structures

リストやツリーなど基本的なデータ構造が効率的だということを説明していた

9.3 Persistent data structures libraries

Clojure の提供するデータ構造、データ操作を、他のプログラミング言語でもライブラリとして利用できるようになっていることを説明していた

9.4 Persistent data structures in action

Lodash の _Immutable へ置き換えるだけで元のコードはほとんどそのまま動く

9. Summary

  • 不変コレクション永続化データ構造 は違う概念
  • 構造化共有が利用できると、元の値を破壊しないで効率的に新しい値を作ることができる

10 Database operations

10.1 Fetching data from the database

  • 普通は 遅延バインディング と言えば実行時に呼び出す関数を解決することを指す
    • このセクションでは、未知の値を既知の型として解釈することを指している
  • クエリごとに JSON Schema を書いてデータ型を検証する

10.2 Storing data in the database

  • 例えば Java では Map コレクションの要素にアクセスするとき map.item1 のようなドット記法は使えない
  • だから DOP の考え方を説明するときは汎用的な記法にする
    • 例えば Lodash なら _at(map, ["item1"]) と書ける

10.3 Simple data manipulation

  • データストアに保存し、取得できるフィールド名と、アプリケーションの使用したいフィールド名は異なる場合があるから、アプリケーション側で対応表を用意して、変換すればいいということを説明していた
    • 前のセクションで木構造を探索するCPU時間を気にしていたのに、突然富豪的な処理を導入しているのは不思議

10.4 Advanced data manipulation

  • SQL レベルでデータを操作している意味がわからない
    • システムの扱うすべてのデータはメモリ上に木構造で展開されていたはず
    • 差分を計算してアトミックに更新できるのではなかったのか

11 Web services

  • 10章データベース操作と同じく、アプリケーションの関心事だけを扱っている雰囲気

11.1 Another feature request

11.2 Building the insides like the outsides

参考情報

西暦1999年に好きだった音源を探してる

タイトルもアーティストもレーベルも覚えてないんだけど、頭の中でずっとループ再生できるくらい好きな音源がある。

高専に在学中の1995年から1999年の間にアナログレコードで購入して、もう手元には残ってない。

YouTube で音源を探すのは諦めていたけど、最近になってからSpotifyで探す意欲が湧いたので、覚えてるワードで検索したり、アーティストページのalso likeをさまよっている。

だんだん近づいてるはずだけど、最近は同じところに戻ることが増えていて発見がない。