概要
ここでは、週一回ごとに、定期的に研究の進捗などを定期的に記録を取ることとします。主に、卒論の延長線上として開発している、2つ目の試作品について書いていきます。
ここでは、週一回ごとに、定期的に研究の進捗などを定期的に記録を取ることとします。主に、卒論の延長線上として開発している、2つ目の試作品について書いていきます。
この記事を作った動機 2026/9/16 に至るまでの間で OneNote 代替に関して、実装をするなど研究を進めているうちにわかったことなどを簡易的に記録する。 次に軽くやりたいことを記述 割り込みの呼び出しが、コマンドモジュールから、コマンドコントローラのプロセスを介して、割り込みのプロセスへ IPC するようにする。 フロントエンドの割り込みの実装を今の試作物の DataServer に適合させる。 フロントエンドが DataServer の拡張機能読込み時に HTML CSS JS としてビルドされて配置され、それがホスティングされるようにデータサーバを実装する。 pexpect のログをファイルシステム上の位置を決めてテキストファイルとしてそれぞれ書き出すようにし、ユーザーにはそれを独立した端末で watch -n 0.1 "cat log | tail -n 10" のようにして動いている様子が確認できるようにする。できれば各コントローラやホスティングのプロセスでも同じようなログの出し方をしたい。 データサーバ実行において、端末セッション維持に使っている pexpect の実装を見直す。subprocess ライブラリを使うように変更するか、pexpect においてログが出るようにしながら、pexpect のタイムアウトでサーバーが強制終了しないようにする。 各拡張機能が設定を持てるように実装する。 拡張機能のファイルの読み書きが衝突しないようにするためのコントローラを実装し、ファイルの読み書きを各拡張機能モジュールに対して、統一したヘルパー関数を経由するようにする。ヘルパー関数は、各コントローラプロセスから、IPC によってファイルを読み書きするためのプロセスにアクセスし、リクエストを送り、結果を待機して各モジュールと接続される。各モジュールは、ファイル読み書きのヘルパー関数を呼び出すとき、リクエストだけではなく、リクエスト完了時やエラー時のコールバック関数を登録し、処理が続行されるようにする。 以下の LLM が吐き出したコードについて調べる。 ## LLM (DuckDuckGo ChatGPT) 出力 調査が必要 ------- ## LLM (DuckDuckGo ChatGPT) 出力 調査が必要 ------- from __future__ import annotations from typing import TYPE_CHECKING if(TYPE_CHECKING): from controller.common import commandModuleArgs ## LLM (DuckDuckGo ChatGPT) 出力 調査が必要 ------- ## LLM (DuckDuckGo ChatGPT) 出力 調査が必要 ------- やったことの詳細 現状の動作の様子 現状としてはかろうじて動くという感じでバグや不具合だらけである。DataServer なのか、それとも卒論の試作物で使いまわしているフロントエンドの実装がいけないのか、切り分けがついていないことも多く、しばらくは調査が必要そうである。特にページコントローラ周りが動作が不安定である様相が見受けられる。これは、拡張機能名とUUIDがモジュール名に加えて解決が必要になったことが影響していると考えられる。 ...
この記事を作った動機 2026/9/9 に至るまでの間で OneNote 代替に関して、実装をするなど研究を進めているうちにわかったことなどを簡易的に記録する。 次に軽くやりたいことを記述 コントローラープロセス間のファイル書き込み衝突を回避する実装 Core拡張機能と、コントローラーにおいて、設定を伝搬するように実装 拡張モジュールにmainSysから共通で提供する関数(インターフェース)を引数として辞書型などにまとめ、モジュールに渡して呼び出せるようにする コントローラーのログを見えるように、マルチプロセッシングに関して調べる コントローラー間をマルチプロセッシングライブラリのIPC実装でつなげる pexpect の端末セッションや、マルチプロセッシングで独立したプロセスとして動くプロセスのそれぞれの出力は、独立したターミナルを立ち上げるようにする。GUI環境であれば、GUIのインストールされているターミナルエミュレーターを複数起動し、それぞれのセッションやプロセスに端末を1つずつ割り当て、ログの可読性向上を図る。 拡張機能を読み込み終わったあと、依存関係に関して不足がないか確認する処理を導入する。具体的には各拡張機能の依存関係リストに対して、読み込んだ拡張機能を線形探索で単純にそれぞれ照合して不足がないか確認する。 卒論の試作物から、フロントエンドをコピーしてきて、今回の試作物の DataServer の動作検証ができるように改変する。Core拡張機能の呼び出し名に対応させ、割り込みとコマンドに関して、それぞれが独立してwebsocket接続を持つようにする。 やったことの詳細 DataServer の起動オプションを追加 DataServer について、拡張機能を読み込むだけの動作と、読み込んだ拡張機能をもとに、DataServer を起動させようとすることを分けてユーザーが明示してそれぞれ操作できるようにするために、argparseライブラリによって以下のようになるように実装した。 以下は、argparseに関する実装が正しくできたかテストした様子である。引数に対してどう動作するか確かめたかったので、実際に拡張機能を読み込んだり、DataServer を起動する機能は一時的にコメントアウトしてテストした。何も出力がターミナルに出ていないとき、引数が受理され、正常に動作したことを示す。 python main.py --loadExtension # 何も出力しない python main.py --startServer # 何も出力しない python main.py --loadExtension --startServer #--loadExtension and --startServer cannot be set at the same time. python main.py --loadExtension aaa #usage: main.py [-h] [--loadExtension] [--startServer] #main.py: error: unrecognized arguments: aaa Core 拡張機能の機能を一時的に制限 卒論で書いた試作物のフロントエンドと今回試作している DataServer 間で一旦動作を確認したいため、すでに実装がある程度できており、卒論時点で動いていたモジュールに限定して動作するように実装を変更した。 変更前 { "name": "Core", "UUID": "589fe65d-639c-42a3-b395-fca2143afd75", "description": "Manage notebook and pages. Provide basic notebook interface.", "frontend":{ "modules": [] }, "DataServer":{ "CommandModules":[ "backend/commands/info.py", "backend/commands/notebookAndPage/createNotebook.py", "backend/commands/notebookAndPage/deleteNotebook.py", "backend/commands/notebookAndPage/getPageType.py", "backend/commands/notebookAndPage/pageInfo.py", "backend/commands/notebookAndPage/updatePage.py", "backend/commands/notebookAndPage/copyPage.py", "backend/commands/notebookAndPage/createPage.py", "backend/commands/notebookAndPage/deletePage.py", "backend/commands/notebookAndPage/movePage.py", "backend/commands/notebookAndPage/renamePage.py", "backend/commands/notebookAndPage/addTag.py", "backend/commands/notebookAndPage/createTag.py", "backend/commands/notebookAndPage/deleteTag.py", "backend/commands/notebookAndPage/getTagList.py", "backend/commands/notebookAndPage/queryTag.py", "backend/commands/notebookAndPage/removeTag.py", "backend/commands/notebookAndPage/fileAdd.py", "backend/commands/notebookAndPage/fileData.py", "backend/commands/notebookAndPage/fileDelete.py", "backend/commands/notebookAndPage/fileInfo.py" ], "InterruptModules":[ "backend/interrupts/newInfo.py", "backend/interrupts/updatePage.py", "backend/interrupts/updateTag.py" ], "TaskModules":[ "backend/tasks/pageCleaner.py", "backend/tasks/showPingMessage.py" ] }, "extensionDependencies":[ ] } ...
この記事を作った動機 2026/9/2 に至るまでの間で OneNote 代替に関して、実装をするなど研究を進めているうちにわかったことなどを簡易的に記録する。 次に軽くやりたいことを記述 まだ拡張機能の読み込み部分は、とりあえず書いたという段階であり、パスやインポートの記述がおかしかったりするおそれがあり、デバッグが必要である。また、拡張機能を読み込んで DataServer が動作する事を確認するために、Core 拡張機能を完成させる必要がある。 Core 拡張機能を完成させるためには、主にパスの解決が正しく出来るように、拡張機能のモジュール呼び出しにおいて、どうやってmainSysと提携させるかが課題となっている。今具体的に考えている実装の一つとしては、モジュール呼び出し時に、DataServer のルートのパスや Notebook へのパスは、拡張機能ではない DataServer 側の組み込みの実装としてパスを解決しモジュールに伝える機構を実装することが考えられた。 また、mainSysについては、Python の仮想環境機能を使うことが考えられた。依存関係などをインストールするとき、既にインストールされている Python 環境を汚したりしてしまうのは避けたいと考えた。仮想環境は、存在しなければ拡張機能読み込みの段階で初期化し、存在すればそれが DataServer 起動時などに有効化されて使われるというような事を考えている。 今回の試作物としては、とりあえず DataServer が拡張機能を介して動作するということを最低限の目標としたいと考えた。そこまでできたら次は、3つ目のプロトタイプとして今度はフロントエンドをなんとかするというロードマップにしようかなと作業と進捗状況から思ったところであった。フロントエンドには、zustand のストアにおける値が異なるストア間で重複しているなど、SQLの文脈におけるデータ項目の重複と正規化の問題があり、その点がまず修正点としてあげられる。 DataServer において、WebSocket によるフロントエンドとの接続に関してセッションを管理したい。フロントエンドが接続してきたら、それぞれのフロントエンド自体をUUIDなどで識別して、正しく Command や Interrupt の経路がつながっているか管理することを考えている。 やったことの詳細 Core 拡張機能を実装 完全ではないが、とりあえず最低限の機能を DataServer に与えるために、Core 拡張機能を作成し、中身には前回のプロトタイプで存在していた、command、interrupt、task の実装を移植した。移植したと言っても配置して、manifest.jsonにまだその存在を記述しただけであり、まだ今回の試作物に適合させる実装がこれから必要である。 manifest.jsonの実装についても変更点があり、DataServerの項目についてCommandModules、InterruptModules、TaskModulesの3つに分けて、モジュールを記述するようにした。それぞれは、拡張機能のmanifest.jsonがあるフォルダを起点としたモジュールまでの相対パスが記述されている。それぞれのモジュールは1つのスクリプトで1つのモジュールという構成にしており、[moduleName].pyというモジュールであれば、内部にある関数名は必ず、def [moduleName](request,websocket):の形態を取る必要がある。パスの解決の問題により、今後モジュールが共通して受け付けるべき引数が増える可能性がある。 "DataServer":{ "CommandModules":[ "backend/commands/info.py", "backend/commands/notebookAndPage/createNotebook.py", "backend/commands/notebookAndPage/deleteNotebook.py", "backend/commands/notebookAndPage/getPageType.py", "backend/commands/notebookAndPage/pageInfo.py", "backend/commands/notebookAndPage/updatePage.py", "backend/commands/notebookAndPage/copyPage.py", "backend/commands/notebookAndPage/createPage.py", "backend/commands/notebookAndPage/deletePage.py", "backend/commands/notebookAndPage/movePage.py", "backend/commands/notebookAndPage/renamePage.py", "backend/commands/notebookAndPage/addTag.py", "backend/commands/notebookAndPage/createTag.py", "backend/commands/notebookAndPage/deleteTag.py", "backend/commands/notebookAndPage/getTagList.py", "backend/commands/notebookAndPage/queryTag.py", "backend/commands/notebookAndPage/removeTag.py", "backend/commands/notebookAndPage/fileAdd.py", "backend/commands/notebookAndPage/fileData.py", "backend/commands/notebookAndPage/fileDelete.py", "backend/commands/notebookAndPage/fileInfo.py" ], "InterruptModules":[ "backend/interrupts/newInfo.py", "backend/interrupts/updatePage.py", "backend/interrupts/updateTag.py" ], "TaskModules":[ "backend/tasks/pageCleaner.py", "backend/tasks/showPingMessage.py" ] }, manifest.jsonの他の変更点としては、別の拡張機能を依存関係として書けるようにした。具体的にどうやって異なる拡張機能間を上手く提携させるか、どういう課題があるかはみえていないが、とりあえず拡張機能の依存関係を記述できるようにした。例は以下のようなものである。 ...
この記事を作った動機 2026/8/26 に至るまでの間で OneNote 代替に関して、実装をするなど研究を進めているうちにわかったことなどを簡易的に記録する。 次に軽くやりたいことを記述 mainSysの各サブシステムがプロセスとして独立しているので、それらのプロセス間通信について、調べて実装する。commandから、interruptが呼び出せるようにするなど、実装を行う必要がある。threadingとは異なり、メモリ空間が共有されていない点に留意する必要がある。 またコマンドのモジュール読み込み部分については、extensionMoludes = {moduleFunc:[moduleFuncName],...}という形態で、前回の辞書型の実装を単に拡張される前提で書き換えただけであるが、それだとどのコマンドがどの拡張機能に属しているか管理が不十分になると思われる。これに対して考えられることとしては、前回の試作物のように、コード上の関数名と辞書型のキーの値を同じにするのではなく、キーの部分については識別性を上げるために、extensionName/moduleFuncNameのようにすることが考えられた。また同名の拡張機能のためには、extensionName-UUIDの一部/moduleFuncNameのようにして重複を防止することが考えられた。 また今回の実装では、WebScoket の経路が、commandとinterruptで分かれており、それぞれは混同されない仕組みとした。現状では使用されるポートが前回と異なりハードコードで決め打ちとなっている。commandのサブシステムに関してはlocalhost:50097に、interruptのサブシステムに関しては、localhost:50098にホスティングされる。 今回試作する DataServer を前回の試作物のフロントエンドに適用するには、前回の試作物のフロントエンドの装の調整が必要である。 やったことの詳細 主に以下の項目について実装を進めた mainSys の実装を進めた command、interrupt、taskについてそれぞれ、具体的な中身を記述した。その過程において、拡張機能を読み込みには、command、interrupt、taskのそれぞれにおいて、決まった関数の Import と extensionMoludes = {moduleFunc:[moduleFuncName],...} の設定を必要とし、DataServer 起動時にそれらが文字列として構築されることとした。 mainSys の起動をするためのコードの実装を進めた mainSysを起動するための、mainSys/main.pyでは、あくまでフロントエンドやデータ転送の機能のホスティングやcommand、interrupt、taskを常駐させるためにプロセスを生成したり、終了時の例外処理に特化させた。当初はここにモジュールの Import や読み込みは集約させようと思っていたが、それだと引数などとして command、interrupt、task などのコントローラにそれぞれ参照を渡したりする手間が発生することが分かったため、command、interrupt、task のコントローラのスクリプト群に直接組み込むことで、実装を単純にしようとした。 前回の試作品からいくつかのコードを移植 今回の試作物は、拡張機能によって成り立つシステムという事を想定しているため、それ以外の部分については前回の試作物から移植して調整したものを使っている。具体的には以下のような部分が移植されている。 WebSocket 接続を待ち受ける実装 NotImplementedResponse、malformedRequestResponse、notFound といった DataServer がコマンドの動作に関して常に最低限必要としているレスポンス実装 showJSONMessage、malformedRequestChecker、receiveLoop などといった、コンソールに DataServer の送受信内容を表示する関数や、受信データの確認、WebSocket の実装に関するヘルパー関数について、引き継いでいる。 研究に関係ありそうなブログ記事 今回は特になし。 参考にしたサイトとか 今回は特になし。
この記事を作った動機 2026/8/19 に至るまでの間で OneNote 代替に関して、実装をするなど研究を進めているうちにわかったことなどを簡易的に記録する。 次に軽くやりたいことを記述 とにかく中身の実装を進める。DataServer 周りをとにかく終わらせて、とりあえず卒論のフロントエンドに対して、DataServer を今回作る試作物に置き換えて動作するくらいにはしたい。 やったことの詳細 内部構造について 大まかには、DataServer 周りのシステムのディレクトリ構造を卒論時点のものとは大幅に変更した。また、スクリプトを配置して、具体的な内容が書き始められるように、擬似コード的な感じでスクリプトの各所にコメントを記述したりした。大きな変更点は、“具体的な実装"をなるべく含めないようにすることで、抽象度を上げ、データの器として DataServer を機能させるための下地を作ったという点である。また、拡張されるのは DataServer だけではなく、フロントエンドも対象であり、DataServer と整合性をもって動かす必要があるため、DataServer の一部としてフロントエンドを組み込んだ。 卒論時点の DataServer のディレクトリ配置 ├── commands │ ├── _index.py │ ├── fileAPI │ │ ├── fileAdd.py ... │ ├── info.py │ ├── notebookAndPage │ │ ├── copyPage.py │ │ ├── createNotebook.py │ │ ├── createPage.py ... │ ├── tag │ │ ├── addTag.py │ │ ├── createTag.py ... │ └── template.py ├── configure.py ├── controller.py ├── helper │ ├── _index.py │ ├── common.py │ ├── loadSettings.py │ └── netwrok.py ├── interrupts │ ├── controller.py │ ├── newInfo.py │ ├── updatePage.py │ └── updateTag.py ├── jobs │ ├── pageCleaner.py │ └── showPingMessage.py ├── main.py ├── requirements.txt ├── settings.json ├── tasks.py ... 今回の試作品のディレクトリ配置 ├── extensionLoader │ ├── common.py │ ├── dataserver.py │ ├── frontend.py │ ├── main.py │ └── template │ ├── dataserver.py │ └── frontend.tsx ├── extensions │ └── readme.md ├── frontend ├── main.py ├── mainSys │ ├── controller │ │ ├── command.py │ │ ├── interrupt.py │ │ └── task.py │ ├── hosting │ │ ├── fileTransfar.py │ │ └── frontendServe.py │ └── main.py └── settings.json 今回の試作物の構成について軽く説明 今回の試作品の各ディレクトリやファイル配置についての説明としては以下のとおりである。 ...