Rust 版 Snowflake ドライバーで非同期クエリをサポートしました

こんにちは、スタッフエンジニアの @kenkooooです。estie が OSS として公開している Rust 版 Snowflake ドライバーの snowflake-connector-rsのアップデートについてお知らせします。

Snowflake で時間のかかるクエリ

Snowflake は SQL でクエリが書けるデータウェアハウスですが、実態としては HTTP サーバーとして動いていて、クライアントは HTTP でクエリを投げたり結果を受け取ったりします。

Snowflake は非常にパワフルですが、クエリによっては実行に時間がかかるものもあります。そういったクエリを実行する時、Snowflake は以下のような形式のレスポンスを返します。

{
    "data": {
        "queryId": "01b056d5-0001-25f6-0000-6bb504856e2e",
        "getResultUrl": "/queries/01b056d5-0001-25f6-0000-6bb504856e2e/result",
        "queryAbortsAfterSecs": 300,
        "progressDesc": null
    },
    "code": "333334",
    "message": "Asynchronous execution in progress. Use provided query id to perform query monitoring and management.",
    "success": true
}

実行結果を直接返す代わりに、実行結果が表示される予定の URL を返しています。クライアントはこの URL をポーリングすることで実行結果を得ることができます。

非同期クエリのサポート

上記のような非同期実行をサポートする機能は以下のプルリクエストで実装されました。
[Poll getResultUrl to handle async execution by Jlinnister · Pull Request #22 · estie-inc/snowflake-connector-rs ]

公式の Go SDK の実装を参考にしたとのことです。Jlinnisterさんありがとうございます。 今回実装された機能は、以下のように確認することができます。

let client = SnowflakeClient::new(
    &username,
    SnowflakeAuthMethod::Password(password),
    SnowflakeClientConfig {
        account,
        warehouse,
        database,
        schema,
        role,
        timeout: None,
    },
)?;

let session = client.create_session().await?;
let query = r#"CALL SYSTEM$WAIT(120)"#;
let rows = session.query(query).await?;

assert_eq!(rows.len(), 1);
assert_eq!(rows[0].get::<String>("SYSTEM$WAIT")?, "waited 120 seconds");

Snowflake には SYSTEM$WAIT という関数があり、待機させることができます。これでクライアントで非同期実行をテストすることができます。

ところで、この関数はクライアントで非同期実行をテストする用途にしか使い道が無いような気がしています。他の用途をご存知の方がいれば教えてください。

おわりに

今回のアップデートは v0.2.0 としてリリースされています。これで Rust から Snowflake で時間がかかるクエリも実行できるようになりました。Rust でデータエンジニアリングを楽しむお供にしていただければ幸いです。

estieでは今後の事業成長にあたって新しい仲間を引き続き探しております。エンジニアを幅広く採用しておりますので、興味がありましたらカジュアル面談からご応募お待ちしております!

jobs.estie.jp

© 2019- estie, inc.