TemporalというWorkflow Engineについて
Podcastを聴いていてたまたまTemporalというWorkflow Engineを見つけて、気になったので情報を集めてみました。
Temporalという会社
Temporalというプロダクト
- Workflow Engine
- AWS Step FunctionsとかAzure Durable Functionsと同じような機能を持っている
- Single Stateful Service in your whole cloud that makes everything in your cloud stateless
- 解決してくれる課題
- Cloud Native Architectureで、スケールしやすくするためにはなるべく作るものはStatelessにしていきたい
- でもWorkflowを組むにはどこかしらにStateは必要になる
- Stateの管理は難しいし複雑になりやすい
- そこでまるっとおまかせできるのがTemporal
- TemporalがOrchestratorとしてStateをハンドリングしてくれる
- アーキテクチャ
- 現時点でサポートしてる言語
Workflowとは
例えばフードデリバリーの例
- マッチング
- ドライバーをレストランに行かせる
- レストランからお客さんところにドライバーを行かせる
- お客さんに評価させる
という一連の流れがWorkflowで、これはすべてうまく言った場合の流れ。この他にも失敗した場合のリトライだったり、タイムアウトをどのくらいにするか、とかの考慮お必要になる。このあたりのリトライ、タイムアウト、ヘルスチェック周りもTemporalがハンドリングしてくれる。
Temporal使ってる人たち
所感
- Step Functionsだとローカルでテストしづらいから、どこででも動かせそうなTemporalに期待したい
- ↑のことからローカルやCIでのテストができるのに期待
- ユニットテストではTime Skipping(執筆時点でTypeScript版にはまだ無い)が使える
- Saga Patternについてもいい感じに実現できそう
参考
Udemyなどオンライン講座を宅録するときの諸注意
Udemyの講座をレコーディングするにあたって、自分なりに工夫した点を記録しておきたかったので記事にします。随時気づいた点があれば追記します。
正直、日本で綺麗に宅録するのは鬼門です。
前準備
動画のバックアップ先
- レコーディングした動画をどこにバックアップしておくか、というのを早い段階で決めておく
- 今回は元々契約してるOneDriveをひとまず選択
- 落ち着いたタイミングでHDDに移すかも?(OneDriveの容量を逼迫するので)
レコーディングする画面の解像度
- 1920x1080の解像度が最低限あること
- Macbook標準の画面サイズだと比率が合わないので要注意
- 必ずレコーディングテストすること
- ここを甘く見ると、全部のレコーディングがパーになるかもしれないので、入念にチェック!
レコーディング用のOSユーザー
- レコーディング用のOSユーザーを用意しておいたほうが良い
- 普段のユーザーでやると、変なものが画面に写るかもしれないし、開発環境が世間の人々と大きく異なっている可能性がある
- なので、なるべくクリーンな環境にするためにも専用のユーザーを用意しておく方がおそらく良い
ソフトウェア
- レコーディングにはCamtasiaを使用
www.techsmith.com
- 特段使い勝手が言いわけではないんですけど、昔から使ってるので
- ノイズ軽減にKrispを使用 krisp.ai
- レコーディングのバックアップにはOneDriveを使用
機材
- オーディオインターフェースはYAMAHA AG03
- 無難にYAMAHA AG03を選択しています。こだわりは特にありません。
- マイクは「SHURE Beta 58A」
- 欲を言えばコンデンサーマイクを使いたいんですけど騒音が多い環境に住んでいるので超単一指向性のBeta 58Aを採用
- マイクスタンドは「Luling Arts マイクスタンド」
- キーボードの振動を拾わないためにも、キーボードが乗っている机には取り付けないほうがいいです
- マウスパッドは「エレコム マウスパッド デスクマット 超大判 MP-DM01BK」
- キーボードの音があまりレコーディングに影響ないように気持ち程度に敷いてます
- ヘッドホンには「Sony WH-1000XM3」
- 子供も家で騒ぎまくったりしてる中で編集作業をしたりするので、ノイズキャンセリングが優秀なヘッドホンを選択
- キーボードは「Ultimate Hacking Keyboard(モジュール付)」
ultimatehackingkeyboard.com
- 編集作業のとき、モジュールにショートカットを割り当てているとはかどります
- デスクは昇降式のFLEXISPOT
- レコーディングはスタンディングで行う方が元気な声が出ます
その他
スケジューリング
レコーディングのスケジュールをたてておくのは結構大事です。
- 近隣のスケジュール確認
- 学校の長期休暇期間かどうか(家の付近で子供たちが騒ぎそうな期間かどうか)
- 工事が行われる予定があるかどうか(道路工事とか建物の工事がある日はレコーディング厳しいです)
- 夏はセミがうるさいので要注意
- 一日にレコーディングできる量は、多くても40分程度
- 編集とかを考えると、それ以上やるとメンタルもフィジカルも持たない
レコーディング
レコーディング前の確認
- OneDriveアプリがOFFかチェック
- OneDriveのクライアントがONだと、動画と音声がずれる傾向がありました
- 動画の保存先がOneDriveのフォルダだったので、CPU負荷が影響していたのかもしれません
- なので、レコーディング前には必ずOneDriveがOFFになってることをチェック
- 外付けWebカメラをはずす
- マイクが入っているかチェック
- これ結構侮れないです。ちゃんとマイク入力があるか確認が必要です
- レコーディング終わったあと、音声が一つも入っていないのを見ると泣けます
- KrispがONかチェック
- ノイズキャンセリングされているかチェック
- デスクをスタンディングモードにする
- 立って発声するほうが明らかに良い声が出ます
編集
- 2倍速で編集
- 1倍速で編集していると時間がかかりすぎるので、動画を2倍速にして編集作業を行う
- Camtasiaならこんなメニューから変更可能
- ノイズ除去を適用
- 適宜、デフォルトのレコーディング状態でノイズが入るようだったら、ノイズ除去のエフェクトを適用
- Camtasiaだとわかりづらいんですけど、ノイズ除去っていうエフェクトがあります
- UHKのショートカット割り当てで編集作業効率化
- 「トラックの分割」、「削除」、「再生位置を戻す」をキーに割り当てておけばものすごく効率上がります(指の負担も)
動画のエキスポート
- 普通にmp4で出力すればOK
その他注意点
OsoでRBACを実装してみる
はじめに
久しぶりに権限周りに関するエントリです。 Osoと呼ばれるライブラリを最近ふとしたタイミングで見つけたのでいろいろと実験してます。
Osoについて詳しく書ける時間ができたら書きたいのですが、この記事では軽く紹介するだけにとどめます。
- Osoは認可(Authorization)に特化したライブラリ
- コアな部分はRustで作られてますが、Node.js/Python/Go/Ruby/Rust/Java用のライブラリが提供されてる
- PolicyにはPolarと呼ばれる言語が使われている(OPAで言うところのRego)
権限や認可についてあまり馴染みが無い方は、以下の記事を読んでみると雰囲気が少しつかめるかもしれません。
また、英語に抵抗が無い方であれば、Osoが書いてるAuthorization Academyっていう神ドキュメントがあるので、そちらをぜひ読んでみてください。
使ってみた
公式ドキュメントはかなり頑張って書かれてはいるものの、自分のコード(JSとか)とPolarがどのように関わってるのかが、実際に手を動かしてみないとわかりづらかったので、サンプルアプリでRBACを実装してみました。
ベースとなってるのは以下のトピックです。
RBAC構成
以下のような権限を実現したいと思ってます。
「誰が(Actor)」、「何に(Resource)」、「何を(Action)」して良いのか。
という観点でこの図を表現すると、
- contributerはRepositoryをreadすることができる
- maintainerはRepositoryにpushすることができる
上記は結構単純です。Role(contributor/maintainer)にAction(read/push)が紐付いてて、対象がRepositoryになってます。
ここに、さらにちょっと複雑な要件も増やします。
- contributerができることは、maintainerもできる
- なので、maintainerはRepositoryをreadすることもできる
- Repositoryを所有しているOrganizationのownerであれば、maintainerと同等なことができる
- なので、単純にRoleにActionが紐付いてるわけではなく、Resourceの関連(Relation)も考慮している
上記を満たすためのPolicyを、Osoを使って書くことができます。
そこで登場するのがOsoのDSLであるPolarです。
Polar
Polarについても詳しいことは割愛してしまいますが、Policyを定義するためのOsoが作った専用の言語です。気になる人は以下のドキュメントを読んでみましょう。
先程の要件を満たすPolarを書くと、(公式ドキュメントそのまんまですけど)以下のようになります。(シンタックスハイライトが無いので、キャプチャを貼り付けます)
全部で30行ほどのPolicyですが、結構Osoの裏側でこれだけでもいろいろなことが起きてます。
allowとhas_permission
エントリポイントとなってるのが1行目のallowです。自分のコード(JSなど)からOsoを呼び出すときの入り口となる部分です。 このallowがtrueかfalseなのか、という判断をPolicyに基づいてOsoが判断してくれます。allowはPolarに最初から組み込まれているRule Typeになります。
最初から組み込まれているRule Typeについては以下参照。
そして、allowの中身は以下のように定義しています。
allow(actor, action, resource) if
has_permission(actor, action, resource);
has_permissionがもし(if)trueだったら、allowもtrueという意味になってます。このhas_permissionも、Polarに最初から組み込まれている型になります。このhas_permissionの定義は、後ほどShorthand Ruleを書くときに重要になってきます。
has_roleとhas_relationに関してはいったん置いておいて、次はactorとresourceについて見ていきましょう。
actorとresource
actorとresourceの定義を見てみましょう。書き方は下のような感じです。
actor User {} resource Organization { # ... } resource Repository { # ... }
actorは「誰が」に対応する存在となります。で、resourceが「何に」の「何」に該当します。ここで宣言したactorとresourceに関しては、自分のコードと紐付けるときにそれぞれ、コード側のどの型に対応するのか、というのをマッピングする必要があります。
具体的にはJavaScriptであれば以下のようなコードで、OsoにUser, Organization, Repositoryを登録します。
class Organization {} class Repository {} class User {} oso = new Oso(); oso.registerClass(Organization); oso.registerClass(Repository); oso.registerClass(User);
これで、JS側のエンティティと、Polarの中のエンティティを紐付けられているということです。
では、resourceの中身を見ていきましょう。まずはOrganizationから。
resource Organization { roles = ["owner"]; }
rolesという定義があります。これはRBAC(Role-Based Access Control)をする上で便利で、対象となるResourceに紐づくことのできるRoleを定義することができます。なので、ここではOrganizationというResourceに、ownerというRoleが紐づくことができると言ってます。
次にRepositoryを見てみましょう。こっちはもっと複雑です。
resource Repository { permissions = ["read", "push"]; roles = ["contributor", "maintainer"]; relations = { parent: Organization }; # An actor has the "read" permission if they have the "contributor" role. "read" if "contributor"; # An actor has the "push" permission if they have the "maintainer" role. "push" if "maintainer"; # An actor has the "contributor" role if they have the "maintainer" role. "contributor" if "maintainer"; # An actor has the "maintainer" role if they have the "owner" role on the "parent" Organization. "maintainer" if "owner" on "parent"; }
permissionsという定義があります。これは、対象となるResourceに対して、「何ができるか」というのを定義します。なので、ここではRepositoryに対して「readとpushを行うことができる」と定義してます。
rolesを見てみると、Repositoryに紐づくRoleはcontributorとmaintainerだと定義しています。
次に登場するのがrelationsの定義ですが、いったん飛ばしましょう。
まずは、3つほど文字列とifで構成されてるRuleを見てみましょう
"read" if "contributor"; "push" if "maintainer"; "contributor" if "maintainer";
読みやすいといえば読みやすいと思います。「contributerならreadできる」、「maintainerならpushできる」、「maintainerであればcontributerでもある」という感じです。
これは何なのかというと、Shorthand Ruleというものになります。Shorthandと言ってるように、要は省略記法です。
通常のRuleで表現すると以下のとおり。
$x if $y; => rule1(actor: Actor, $x, resource: $Type) if rule2(actor, $y, resource);
resource: $Type
の $Type
に関しては、どのresource内で書かれていたかによって変動するということです。今回はresource Repositoryで使ってるので以下のようになります。
$x if $y; => rule1(actor: Actor, $x, resource: Resource) if rule2(actor, $y, resource);
で、$x
がもしpermission
であれば、rule1
はhas_permission
に置き換わりますし、 role
であれば、has_role
に置き換わります。同様なことが$y
でも言えます。
なので、
"read" if "contributor"; ↓ has_permission(actor: Actor, "read", resource: Repository) if has_role(actor, "contributor", resource);
というように読み換えることができます。ここでシレッとhas_roleを出しましたけど、これもまたPolarに最初から組み込まれているRule Typeの一つです。
先程は飛ばしましたが、あらためてhas_roleの定義を見ると、以下の通りです。
has_role(user: User, name: String, resource: Resource) if role in user.roles and role.name = name and role.resource = resource;
これを見たときにuser.roles
とかrole.name
ってどこから現れたんだって思うかもしれません。ここが自分のコード(JSとか)とマッピングした型の情報になります。
class Role { constructor(name, resource) { this.name = name; this.resource = resource; } } class User { constructor(name) { this.name = name; this.roles = new Set(); } assignRoleForResource(name, resource) { this.roles.add(new Role(name, resource)); } }
なので、has_roleのRuleが言っていることは、「もしuserのrolesの中で、role.nameが、引数で渡されたnameと一致して、role.resourceもresourceと一致するなら、確かにnameというRoleを持っているね」ということです。
もう一例みておくと
"contributor" if "maintainer"; ↓ has_role(actor: Actor, "contributor", resource: Repository) if has_role(actor, "maintainer", resource);
というRuleもありました。これは「「maintainer」Roleを持っているのであれば、「contributor」Roleも持っていることにする」という意味があります。Roleの継承っぽいことができるイメージです。
では、最後に残っているのが以下のルールです。
"maintainer" if "owner" on "parent";
Shorthand Ruleなのですが、今回はon
がついてます。これはRelationを使ったShorthand Ruleになります。
$x if $y on $z; => rule1(actor: Actor, $x, resource: $Type) if rule2(actor, $y, related) and has_relation(related, $z, resource);
今回の場合であれば
"maintainer" if "owner" on "parent"; ↓ has_role(actor: Actor, "maintainer", resource: Repository) if has_role(actor, "owner", related) and has_relation(related, "parent", resource);
になります。「親Resourceにowner Roleを持っていて、Repositoryが、親Resourceとparentのリレーションをもっているのであれば、Repositoryに対してmaintainer Roleを持っているのと同等とする」という意味になります。
ここで登場しているのがhas_relationのRuleです。そして先程飛ばしていたresourceに定義しているrelationsも深く関係しています。
relations = { parent: Organization };
これは、Resource同士の「関連」を定義するときに使えます。ここで言っていることは、「RepositoryはOrganizationとparentリレーション
を通して関連づいている」ということです。「parentリレーションってなに?」ってところで登場するのが、has_relation
の定義です。
has_relationもまた最初から組み込まれてるPolarのRule Typeです。この中身に、Resource同士の「関連」を定義します。今回の定義を見てみると以下のとおりです。
has_relation(organization: Organization, "parent", repository: Repository) if organization = repository.organization;
これは、「もしorganizationが、repositoryに定義されているorganizationと一致するなら、OrganizationとRepositoryはparentリレーションを持っている」と定義しています。なので、Resourceの親子関係を持たせることができているのです。ちなみにここで登場しているorganizationやrepositoryは、自分のコード(JSとか)で定義した型のことです。それぞれ以下のように定義しています。
class Organization { constructor(name) { this.name = name; } } class Repository { constructor(name, organization) { this.name = name; this.organization = organization; } }
これでPolarによるPolicyの定義が完了します。
テスト
では、これらの情報を使って実際にテストしてみましょう。まずはOsoに、Polara側で使うJavaScriptのclassを登録しておきます。そして、PolicyをOsoのloadFiles
を使って読み込みます。
oso = new Oso(); oso.registerClass(Organization); oso.registerClass(Repository); oso.registerClass(User); await oso.loadFiles([`${__dirname}/../policies/main.polar`]);
あとは、セットアップとして登場人物たちを用意します。
再掲しますが、以下のような関係になるようにします。
コード的には以下のような感じです。
org = new Organization('ACME'); repo = new Repository('ACME App', org); alice = new User('Alice'); alice.assignRoleForResource('contributor', repo); bob = new User('Bob'); bob.assignRoleForResource('maintainer', repo); tom = new User('Tom'); tom.assignRoleForResource('owner', org); jane = new User('Jane'); jane.assignRoleForResource('guest', repo);
あとは、Osoを使って、permissionが許可されるかどうかを判断してもらうだけです。今回はOsoのisAllowedメソッドを使うことにしました。メソッドにわたすのは、Actor, Permission, Resourceで、Polarのallow
に定義されているパラメータと同様です。
// contributorはreadだけできる expect(await oso.isAllowed(alice, 'read', repo)).toBe(true); expect(await oso.isAllowed(alice, 'push', repo)).toBe(false); // maintainerはreadもpushもできる expect(await oso.isAllowed(bob, 'read', repo)).toBe(true); expect(await oso.isAllowed(bob, 'push', repo)).toBe(true); // Organizationのownerはmaintainer同様ではreadもpushもできる expect(await oso.isAllowed(tom, 'read', repo)).toBe(true); expect(await oso.isAllowed(tom, 'push', repo)).toBe(true); // それ以外の人はreadもpushもできない expect(await oso.isAllowed(jane, 'read', repo)).toBe(false); expect(await oso.isAllowed(jane, 'push', repo)).toBe(false);
というように、意図した結果を確認することができました。
以下のリポジトリに実際に動作する例を置いているので、興味がある人は見てみてください。
まとめ
なぜtrueになったのか、なぜfalseになったのか、についてはまた時間のあるときに書きます。
また、この記事はOsoのほんの一部しか紹介できてません。真に強力なのは0.20.0から追加されたData Filterです。これは長年僕が悩んでいた、権限をデータ取得のときにどう適用すれば良いのか、ということに関する答えの一つになってます。興味がある人はぜひ使ってみましょう。
まとめというほとまとめられませんが、OsoでのRBAC実装を実際にやってみた記録を残してみました。Polarの暗黙的な組み込みRule Typeが最初は「なにこれ?」って感じになります。ドキュメントをしっかり読まないとこれが最初の鬼門になりそうです。あと、自分のコード(JSとか)と連携するために、classをOsoに定義してマッピングするあたりも、最初は関係性を理解するのに苦労しそうです。
と、難しそうな感想を言ってますが、期待はめちゃくちゃしてます。そもそも認可とか権限が難しすぎるんです。オレオレ認可フレームワークでいつも苦しむよりは、ようやく登場したかもしれないベストプラクティスを凝縮したOsoというライブラリを使ってみて、このあたりのドメインもあまり悩みすぎることなく作っていけると良いですね。
WindowsでMongoDBをインストールする
Windowsで開発用にさくっとMongoDBを使えるようにする方法について記録を残しておきます。
概要
- キャプチャを貼ってますが、ウェブサイトの見た目が変わる可能性は高いです
- MongoDBをWindowsのサービスとしてインストールすることもできますが、この記事ではサービスとしてはインストールしません
- シンプルに、使いたいときに
exe
を起動するようにします
- シンプルに、使いたいときに
- MongoDBのバージョンは4系をインストールします
- GUIの管理ツールであるMongoDB Compassはインストールしません
- DBのデータを格納する場所を明示的に指定します(~/webdevbc/data/db)
ダウンロードとインストール
How to Guidesに行きます
Install MongoDBをクリックしましょう
URL的には以下になります。 docs.mongodb.com
「MongoDB Download Center」でダウンロードって言われるのでダウンロードセンターへ行きます。
↑On-premisesを選択します
- MongoDB Community Serverを選択
- バージョンは4系を使いたいので、執筆時点での最新版の4.4.7を選択
- ダウンロードします
ダウンロードしたインストーラを起動します。
Next
AcceptしてNext
こだわりが無ければComplete
サービスとしてインストールしないので、「Install MongoD as a Service」のチェックをはずしてNext (サービスとしてインストールしたい人はどうぞ)
MongoDB Compassはインストールしないので「Install MongoDB Compass」のチェックをはずしてNext (インストールしたい人はチェックをつけたままNext)
Install
Finish
MongoDBの起動
Git Bashを起動してまずはMongoDBのデータを保存する場所を用意します。
$ mkdir -p ~/webdevbc/data/db
MongoDBのデーモンを起動します。
$ /c/Program\ Files/MongoDB/Server/4.4/bin/mongod.exe --dbpath ~/webdevbc/data/db
ログがたくさんでてきて、特にエラーらしきログが出て無ければ成功です。
mongoコマンドでMongoDBのシェルを起動
Git Bashだと微妙にmongoのシェルがうまく動作しないので、コマンドプロンプトを起動します。
mongoコマンドをコマンドプロンプトから実行
"c:\Program Files\MongoDB\Server\4.4\bin\mongo.exe"
下のような結果になったら接続成功!
シェルが動作しているか確認
db
と入力してtest
1 + 2
と入力して3
show dbs
と入力してadmin
,config
,local
などのデータベースの名前
が返ってこれば動作OKです!
WindowsでGit Bashが使えるようにする
GitのエディタとしてVisual Studio Codeを使う手順にしています。 そのため、Visual Studio Codeをあらかじめインストールしておく必要があります。
本記事の執筆時点ではバージョンは2.32.0.2でした。
ダウンロード
msi起動
Next
Next
特にこだわりが無ければデフォルトでOK
Next
デフォルトが「Vim」になっている場合は、 「User Visual Studio Code as Git's default editor」を選択
こだわりが無ければNext
こだわりが無ければNext
Next
Next
Next
Next
Next
Next
Install
すぐに起動したければ「Launch Git Bash」
スタートアップメニューなどから「Git Bash」が起動できるようになります
下のような画面が出たらインストール成功です!
Figmaの便利なショートカットを覚える(Mac)
Figma使っていて便利であろうショートカットを、自分も覚えるためにスクショつきでメモっておく(Mac用です)。
command + \
- Show/Hide UI
ctrl + c
- Color Picker
command + /
- Search
shift + r
- Ruler
option + 1
- Layers / option + 2
- Assets
Shift + 0
- Zoom 100% / Shift + 1
- Zoom to fit / Shift + 2
Zoom to selection
n
- Zoom to next frame / Shift + n
- Zoom to previous frame
PageDown
- Next page / PageUp
- Previous page
command + option + l
- Text align left / command + option + t
- Text align center / command + option + r
- Text align right
command + g
- Group selection / command + shift + g
- Ungroup selection
option
- Measure to selection
1
- Opacity 10% / 5
- Opacity 50% / 0
- Opacity 100%
command + [
- Send backward / command + ]
- Bring forward
command + option + ]
- Bring to front / command + option + [
- Send to back
option + a
- Align left
option + d
- Align right
option + w
- Align top
option + s
- Align bottom
option + h
- Align horizontal centers
option + v
- Align vertical centers
ctrl + option + h
- Distribute horizontal spacing
ctrl + option + v
- Distribute vertical spacing
画面共有先のMac MiniでMagnetがうまく動作しなかったのは競合していたから
夜は仕事部屋で過ごすのが嫌いです。リビングでまったりと過ごしたいのですが、メイン機のMac Miniが仕事部屋にあるのがちょっとした問題。
- 夜は仕事部屋で過ごしたくない
- リビングでまったりしたい
- Mac Miniは仕事部屋にある
- 夜な夜なMac Miniで試したいことがちょいちょいある
- リビングにMac Miniをいちいち持ってきたくない
- Macbook Airは持っている
- Macbook Airで開発はあまりしたくない
という要求があります。一時はMac Miniとモバイルディスプレイを仕事部屋からリビングまで運んでました。ギリギリやれましたけど、長続きしませんでした。
MacからMacへのリモートデスクトップ
Windows機に対してはRemote Desktopしたら割とそのまんまノートPCからメイン機に入って作業できたりします(マルチディスプレイも対応しててとても良い)。
apps.apple.comMacはどうしたものかな、と思って安易に「mac vnc clients best」でググってみたのですが、でてきた候補がどれもしっくり来なかったです。
もうちょっと真面目に調べてみたら、そもそもMacには標準で「Screen Sharing(画面共有)」というアプリがあることを知りました。Mac歴はそれなりに長いつもりでしたが恥ずかしながら初めて知りました...。
ということでリビングからMacbook Airを使って仕事部屋のMac Miniにあっさり接続できました。ショートカットが基本的にMac Mini側で動作してくれるので好感触でした。
- Command + Tabでのアプリ切り替えなどのショートカット
- Command + Shift + SpaceでAlfredが起動する(Macbook AirではなくMac Miniがちゃんと認識)
- クリップボードがMacbook AirからMac Miniに共有される
という感じで、TrackPadによるジェスチャーも「その他のジェスチャ」に該当するもの以外はMac Mini側が認識してくれている雰囲気があります。
イケてないものもあった
「これはいけるぞ!」と希望に満ち溢れていたのですが、問題に気づきます。個人的に愛用している「Magnet」というアプリがうまく動かないのです(ここにきてやっと本題)。
apps.apple.comこれは、フォーカスを当てているウィンドウの大きさをいい感じに左半分、右半分、全画面などに変えてくれるショートカットを提供してくれるMacの常駐アプリです。(WindowsユーザーならOS標準で備わっている機能です) この機能が使えないとそれなりに生産性に響きます。
「Ctrl + Shift + やじるし(←↓→↑)」を割り当てていたのですが、見事に全く反応せず。「Ctrl + やじるし」だったり、「Shift + やじるし」は別のアプリで反応しているので、もしや「Modifier(CtrとかShiftとか)が2つ以上あるとダメ?」と疑ってしまいました。
ただ、よくよく考えてみるとMacbook Air側にもMagnetをインストールしてるから「競合してる?」と思い、Magnetのオプションを見てみたところ、とてもそれっぽいオプションを見つけました。
「"画面共有"を無視する」です。Macbook Air側のMagnetに「画面共有のウィンドウは無視してね」って伝えることができます。
予想は的中!Mac Mini側でちゃんとMagnetもいい感じに動作してくれるようになりました。
ということで夜はまったりとリビングから開発なりなんなりをできているのでした。
まとめ
- MacからMacへのリモートデスクトップにはOS標準の画面共有アプリがいい感じ
- だいたい良い感じに接続先のマシンを操作できる
- ショートカットキーが競合するものもあるので、それは頑張って調査する
- Magnetは「○○を無視する」機能を駆使する