めいぼができて治った話

去年の暮れに左の上まぶたが妙に腫れて眼科に掛かりました。
雑菌が入ったんでしょうということで1週間分の薬を出してもらい、実際に1週間程度で腫れは治まったのですが、ぷくっとした大豆くらいの大きさの突起が残ってしまいました。特に痛くはないものの、触るとこりこりとした異物感があります。

再度眼科で診てもらったところ、霰粒腫という立派な病名をいただきました。俗にいうめいぼというやつです。涙の成分を分泌する脂腺が詰まってできるのだそうです。(ちなみに細菌感染で炎症が起こるのは麦粒腫(いわゆるものもらい)というそうです。)
いくつか薬はいただいたものの、霰粒腫は物理的に詰まりが取れないと治らないそうで、大人の場合は結構な確率で残るので、見た目がどうしても気になるなら手術で簡単に取れますよとのことでした。

左目の上がぽこっと飛び出ているのは確かに気になるけど手術は面倒だなあと思いつつ、しばらく様子を見ることにしました。
脂が詰まっているのだからあっためるのがいいらしいということで、仕事終わりに蒸気が出るアイマスクというのを当てて目を休めたり、お風呂でお湯をまぶたに当てるようにしてみたり。
その甲斐が有ったのか無かったのか、1ヶ月後くらいにはなんとか無くなってくれました。
触るとかすかに違和感が残っていますが、見た目は完全に元通りです。

人によっては霰粒腫は繰り返すこともあるようなので、折りに触れ目の周りを温めるというのは続けていこうと思っています。

強力の Callback プログラミング

こんにちは。開発担当のマットです。

最近、暇の時に、Unity というゲーム・エンジンで色々遊んでいます。
Unity で自由自在にゲームを作ることができ、武器を振り回して街を爆発させるゲームやゾンビー・ゲームやストラテジー・ゲームなど、色々作ったことはあります。

ところで、ゲームは割と複雑なものです。ビジュアルも、アニメーションも、効果音も色々ありまして、プログラムを正しく設計しないと、バグに繋がってしまいます。

従来の書き方

とても簡単な例でゲーム・プログラムの従来の書き方を紹介します。
例のゲームを、「マイ・ペット」と呼びましょう。このゲームにペットを育てることができます。
このゲームを作るには、データを持つクラスと、画面にペットを書き出すクラスは必要でしょう。

1. PetData クラス。
 このスクリプトの中に、ペットの色・サイズ・特徴など、全てのデータを記録しています。
2. DrawPet クラス
 このスクリプトは PetData のデータを使って、ペットを画面に描き出す(描画する)。

普通だったら、ゲームが開始されたら、DrawPet が PetData の中身を見て、ペットを画面に書き出します。

ところで、ゲームの中で「ピンク薬」という魔法なアイテムを使って、ペットの色が「ピンク」になった場合はどうしたらいいでしょう?DrawPet はペットを描き直さないといけませんが、データが変わったことにどうやって気づくでしょうか?

従来な方法は2つあります。

1. PetData の中のデータが変わる時、PetData は DrawPet のファンクションを呼び出す。(Function Call)
2. DrawPet は定期的に、PetData の中身が変わったかを確認する。(Polling)

ところで、どちらにも問題はあります。

Function Call の問題

データが変わった時に、DrawPet のファンクションを呼ぶことは大して悪くはないですが…
気をつけないと膨大してしまうプログラムの書き方です。

例えば、ゲームの中に「ペット詳細」の画面を追加しようと思った時、その「ペット詳細」画面を更新するファンクション・コールも必要になるでしょう。
それとも、色が変わった時、効果音を再生したい場合は?
アニメーションを実行したい場合は?

色のデータを変更するタイミングですべてのシステムにファンクション・コールをしないといけません。
そして、一つでも抜けたらバグ!

直感的ではありますが、問題ですね。

Polling の問題

確かに、DrawPet は PetData を確認したら、上記の問題は解決となります。

ただし、問題はタイミングとなります。DrawPet はいつ PetData を確認すればいいでしょうか?
一瞬で反応する仕組みを作りたければ、毎秒毎秒、何十回、何百回も繰り返しで PetData の中身を確認する必要が生まれてしまいます。

一つのペットなら問題ないかもしれませんが、ペットを増やそうと思ったら、その分の処理も増えます。
そして、DrawPetだけではなく、UI、効果音、アニメーションなど、それぞれのシステムは各々の PetData を連続的に確認する必要になりますね。

しかも、データはそれほど頻繁にかわらないので、無駄な処理ばっかり走っていますね。
ゲームがガタガタと遅くなってしまう恐れはあります。良くないですね。

Callback のチカラ

ここで紹介したいのは Callback の力です。

PetData は DrawPet などのファンクションを呼ぶことも良くないし、
DrawPet は PetData に毎回尋ねるのも、無駄な処理になりますので、
使えばいいのは Callback です。

PetData の方でファンクション参照先を登録できるようにすることです。
これを使って、DrawPet  はPetData に “RedrawPet” というファンクションを登録する。
DrawPet は “RedrawPet” のファンクションを実行するではなく、そのファンクションの参照先を PetData に登録するのだけです。

そして、PetData の方でデータが変わる時、PetData は登録された “RedrawPet” ファンクションを呼ぶことはできます。

このプログラミング方法を使うと、プログラマーはデータのクラスに、描画やUIや効果音やアニメーションのことを一切書くなくて大丈夫です。
それぞれのシステムはデータクラスにファンクションの参照先を登録をして、呼ばれるのを待つだけです。
「呼び返す」の感じですね。なので、Callback と言います。

ぜひ、次のプロジェクトで、Callbackプログラミングをお試しください。

Visual Studio Codeのユーザースニペットの使い方

Visual Studio Code(VS Code) を使う上で便利な機能の一つに「ユーザースニペット」というものがあります。
コードを書く上で同じ内容を書くことがよくあると思います。
よく使うコードは「ユーザースニペット」に登録しておくとコーディングが楽になります。

「ユーザースニペット」とは、コードをあらかじめスニペットに登録することでコードを簡単に呼び出せる機能です。

VS Codeの「基本設定」をクリックします。

ユーザースニペットを開きます。

特定の拡張子のみ適応させたい場合は、「css.json」などのファイル選択します。
「css、scss」両方に適応させたいなど、複数ファイルに適応させたいの場合は、「新しいグローバルスニペットファイル」を選択します。
(ここでは「新しいグローバルスニペットファイル」の方法を紹介しますが、特定の拡張子を選択した場合も同様です。)

ファイル名の入力を求められるので、わかりやすい名前を入力します。
今回は「global」と入力し「Enter」を押しました。

そうすると新しく「global.code-snippets」というファイルができるのでそこにスニペットを登録していきます。サンプルとして下記のような内容を登録します。

{
	"bg": { // スニペット名
		"scope": "css,scss", // 対象言語
		"prefix": "+bg", // スニペットを呼び出すための単語
		"body": [
			"background: url('') transparent top left / auto auto  no-repeat;", // 出力内容
		]
	},
}

保存後に、cssまたはscssファイルを開き、「+bg」と入力すると、候補が現れ、選択すると登録内容が出力されます。
複数登録する場合は下記のように続けます。

{
	"bg": {
		"scope": "css,scss",
		"prefix": "+bg",
		"body": [
			"background: url('') transparent top left / auto auto  no-repeat;",
		]
	},
	"@media": {
		"scope": "css,scss",
		"prefix": "+@media",
		"body": [
			"@media screen and (max-width: 900px){}",
		]
	},
}

下記のようにbodyの中に「$1」「$2」と書くと初期のカーソル位置を設定できます。
Tabキーを押すことで「$1」→「$2」の順に移動します。
${1:900}のように書くことであらかじめ、値を入力することもできます。

{
	"bg": {
		"scope": "css,scss",
		"prefix": "+bg",
		"body": [
			"background: url('$1') transparent top left / auto auto  no-repeat;",
		]
	},
	"@media": {
		"scope": "css,scss",
		"prefix": "+@media",
		"body": [
			"@media screen and (max-width: ${1:900}px){$2}",
		]
	},
}

今回はVS codeのスニペット機能について紹介しました。
コーディングの効率化の参考になれば幸いです!

[Solr]コレクションのコロケーション

はじめに

Solr にはコレクションのコロケーションの機能があります。
この機能はコレクションを跨いだJOINのために必要なものです。

コレクション作成時の指定

コレクション作成APIでwithCollectionパラメータを指定できます。
たとえば以下のリクエストでコレクションc1と同じ場所にコレクションc2を作成します。

/admin/collections?action=CREATE&name=c2&numShards=1&replicationFactor=2&withCollection=c1

ここでいう「同じ場所に」というのは、c1のレプリカが存在するいずれかのSolrノードと同じノード上に、という意味です。

既存のコレクションのコロケーション

コレクション変更APIもwithCollectionパラメータをサポートします。
たとえば以下のようなリクエストです。

/admin/collections?action=MODIFYCOLLECTION&collection=c3&withCollection=c1

ただし、この変更は自動的にはクラスタに反映されません。
多数のレプリカを直ちに移動させ始めるとシステムが不安定になる恐れがあるからです。
このリクエスト実行後に手動でどのようにクラスタを変更させるべきかを知るために、Solr Admin UI の Suggestion ページを利用できます。

コロケーション指定されたコレクションの削除

コロケーションのリンク付けをされたコレクションを削除する場合、先にコレクション変更APIでwithCollection属性を解除しておく必要があります。

/admin/collections?action=MODIFYCOLLECTION&collection=c2&withCollection=

注意事項

  • 1つのコレクションに対してwithCollectionでコロケーション指定できるコレクションは1つだけです。ただしwithCollectionによるリンクを繋げることで任意の数のコレクションをコロケーションさせることができます。
  • withCollection 指定するコレクションが持つシャードは1つだけで、かつその名前は shard1 でなければなりません。

Solrの記事リスト(〜2022年1月)

Prometheus連携

パッケージ管理

JSON Request API

Docket

日付表現

SolrCloudのリーダー選出

SolrCloud

インデックス作成

検索

Solrプロジェクト

その他