タスクに「〜対応」という名前をつけるのを避けたい理由

先日同僚と雑談的に話してたことを書いておく。ソフトウェア開発のバックログにおける話です。

「〜対応」とは

主に差し込みで入ったタスクやなにか早めに単一の解決したい事象のためのタスクに名付けられやすい名前。

あくまでも例としてだが

  • 「マーケから割引データ表示依頼対応」
  • 「監視アラート対応」

みたいなやつ。「〜対応」というのは日本語としてはかなり便利なので、とりあえずバックログに入れておきたいときに使いがち。

なぜ避けたいか

完了基準があいまいになる

タスクを流していく際の問題。

バックログ上のタスクは完了基準を定めておかないと、作業スコープがどんどん広がったり、完了したかどうかを確認する人から見ると完了していないということが作業後にわかったりして不便。「〜対応」という名前をつけるタスクは、そもそもの作業スコープがはっきりしていないことが多く、結果として、作業を始める前に関係者との認識合わせが再度必要になって思ったより時間がかかったり、本来やらなくてよかったところまでやってしまったりするかもしれない。

なにをやっているのかわからない名前になりやすい

作業の透明度についての問題。

「〜対応」というタスクを入れた人がそのままタスクを進める場合に起きがちなケース。やっている人にはある程度道筋が見えているので、作業の進行自体には問題ないことも多い。一方で、他の人からだと話を聞かないとなにをやっているのか見えづらいことがある。実は作業スコープが本来必要なものより大きいこともありえるが、他の人がそれに気づくきっかけが少なくなることがある。

とにかくこなさないとまずいことが起きそうに見える

バックログ上での優先度を決めるときの問題。

「〜対応」ってなんか急ぎっぽいじゃないですか。でも実際はステークホルダーとしては「〜対応」の一部だけ特定の期限までにやってくれればよかったりすることもある。また、「〜対応」のなかにユーザー価値に直結することと技術的タスクが混じっていて、まずはそこの優先順位をつけるべきこともある。

どうするか

いくつか挙げてみる。他にいい方法があったら教えてください。

完了したと明確に言えるタスク名にする

もう少し掘り下げて「〜する」、「〜できる」という方式で名前を考えてみる。最初に挙げた例だと

  • 「マーケから割引データ表示依頼対応」は「〜のページから割引ページが見えるようになる」
    • マーケチームからの依頼という情報はタグなどで表現する
  • 「監視アラート対応」は「〜エラーのアラートが毎朝鳴らないようにする」

みたいに変えると、名前から完了基準が明確になる。加えて、タスクの説明として完了基準を詳しく書いておくとよい。

実は複合的なタスクではないかと疑って分解する

「〜対応」というタスクは実は複合的な作業を表しているということが多い。この場合は、あらためてチームでタスク分解から考えるのがよい。たとえば「監視アラート対応」が

  • 「〜系のエラーは無視して問題ないのでSentryに送らない」
  • 「〜エラーのアラートが毎朝鳴らないようにリトライ機構を入れる」

のように分解できるかもしれない。こういう分解はできればバックログに入れる早い段階でなされるとよい。また、タスクを分解しておくとフロー効率の面でもよい効果があるだろう。

参考

RustでTiberiusを使ってSQL Serverのコンテナに接続する

Microsoftが提供しているSQL ServerのDockerイメージを使うと、デフォルト設定では無料のSQL Server Developer Editionのコンテナを起動できる。

learn.microsoft.com

このコンテナに対してRustからクエリを発行したい。Rustでは、SQL ServerのクライアントとしてPrismaが開発しているTiberiusというcrateがあるので、これを使う。

github.com

今回は0.12.2を使う。

SQL Serverのコンテナを起動する

version: '3'

services:
  db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      ACCEPT_EULA: Y
      MSSQL_SA_PASSWORD: yourStrong(!)Password
    ports:
      - '1433:1433'
    volumes:
      - sqlvolume:/var/opt/mssql

volumes:
  sqlvolume:

これで起動する。mssql/serverのイメージはamd64アーキテクチャにしか対応していないので、AppleシリコンのmacOSかつDocker Desktopを使う場合、Docker Desktopの"Use Rosetta for x86/amd64 emulation on Apple Silicon"を有効にする必要がある1

sqlcmdから接続確認してもよい。

$ sqlcmd -U sa -P "yourStrong(!)Password"
1>

Tiberiusから接続する

ここから先は、すでにtestデータベースにproductsテーブルがあることにする。

create table products (
    id int identity(1,1) primary key,
    name varchar(255) not null,
    price decimal(10,2) not null
);

TiberiusからSQL Serverのコンテナに接続する。macOSでRustのコードを実行する場合、tiberius crateのfeatureとしてrustlsを有効化する必要があることに注意2。デフォルトのnative-tlsを使うとDB接続時にスタックしてしまう現象が見られた。

具体的には、tiberius crateデフォルトのfeatureをすべて無効化して、rustlsをfeatureとして追加する。Cargo.tomlに次のように設定を追加すればよい(デフォルトで有効なfeatureであるtds73も再度追加している)。

[dependencies]
tiberius = { version = "0.12.2", default-features = false, features = ["tds73", "rustls"] }
# ...

また、今回は非同期ランタイムとしてTokioを使う。cargo add tokio tokio-utilしておく。

SQL Serverのコンテナに接続するコードは次のとおり。

use tiberius::{AuthMethod, Client, Config};
use tokio::net::TcpStream;
use tokio_util::compat::TokioAsyncWriteCompatExt;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // 接続設定を作る。デフォルトでlocalhost:1433に接続する
    let mut config = Config::new();
    config.database("test");
    config.authentication(AuthMethod::sql_server("sa", "yourStrong(!)Password"));
    config.trust_cert(); // TLS証明書を検証しない

    // TCP接続する
    let tcp = TcpStream::connect(config.get_addr()).await?;
    tcp.set_nodelay(true)?;

    // DBに接続する
    let mut client = Client::connect(config, tcp.compat_write()).await?;

    // INSERT
    client
        .query(
            "insert into products (name, price) values (@P1, @P2)",
            &[&"Mac Studio", &1999],
        )
        .await?;

    // SELECT
    let stream = client.query("select top 1 * from products", &[]).await?;
    let row = stream.into_row().await?.unwrap();

    println!("{:#?}", row);

    Ok(())
}

注意点としては、開発用なのでTLS証明書を検証しない設定でないと接続に失敗する。DB設定の作成時にtiberius::Config::trust_certを呼んでおけばよい。

このコードを実行すると、次のように出力される。

Row {
    columns: [
        Column {
            name: "id",
            column_type: Int4,
        },
        Column {
            name: "name",
            column_type: BigVarChar,
        },
        Column {
            name: "price",
            column_type: Decimaln,
        },
    ],
    data: TokenRow {
        data: [
            I32(
                Some(
                    15,
                ),
            ),
            String(
                Some(
                    "Mac Studio",
                ),
            ),
            Numeric(
                Some(
                    1999.00,
                ),
            ),
        ],
    },
    result_index: 0,
}

  1. https://github.com/microsoft/mssql-docker/issues/668#issuecomment-1436802153
  2. TiberiusのREADMEによると、"For some reasons the Security Framework on macOS does not work with SQL Server TLS settings, and on Apple platforms if needing TLS it is recommended to use rustls instead of native-tls"とのこと

ghでカレントディレクトリをもとにGitHubの新規リポジトリを作る

GitHub CLI (gh)でカレントディレクトリ配下のリポジトリをGitHubの新規リポジトリとしてプッシュする方法。

$ gh repo create $(basename $(pwd)) --push -s .

--pushでリポジトリ作成とともにローカルのコミットをリモートにプッシュする。そのソースとなるディレクトリを-sで指定する。この場合はカレントディレクトリ.を指定する。GitHubにはカレントディレクトリ名を名前に持つリポジトリが作成される。


余談として、現在のディレクトリ名を$(basename $(pwd))で取得しているが、bashでは${PWD##*/}と書くと外部コマンドに依存せずに現在のディレクトリ名が取得できる(shell parameter expansion)ので、それを使ってもよい。

stackoverflow.com