#ビジネスオペレーション

0 フォロワー · 9 投稿

InterSystems Ensembleは、特定の送信アダプタを使用して外部システムおよびUIと通信する特殊なビジネスオペレーションクラスを提供します。

ドキュメント

記事 Toshihiko Minamoto · 4月 8, 2024 10m read

 

人工知能は、命令によってテキストから画像を生成したり、単純な指示によって物語を差作成したりすることだけに限られていません。

多様な写真を作成したり、既存の写真に特殊な背景を含めたりすることもできます。

また、話者の言語や速度に関係なく、音声のトランスクリプションを取得することも可能です。

では、ファイル管理の仕組みを調べてみましょう。

問題

入力値としてファイルが必要なメソッドについて OpenAI 情報を分析する場合、multipart/form-data を使用してパラメーターを指定する必要があります。

IRIS では、JSON コンテンツを使って POST メソッドへの呼び出しを作成する方法をすでに知っていますが、 この場合、Base64 フォーマットのファイルコンテンツを持つパラメーターを使用するのは非現実的です。

multipart/form-data にファイルコンテンツを含めるには、クラス %Net.MIMEPart を使用する必要があります。

呼び出しにファイルを含めるには、クラスオブジェクト %Net.MIMEPart に関連付けられた Content-Disposition ヘッダーを作成します。

set content = ##class(%Net.MIMEPart).%New()
set contentDisposition = "form-data; name="_$CHAR(34)_"image"_$CHAR(34)
set contentDisposition = contentDisposition_"; filename="_$CHAR(34)_fileName_$CHAR(34)
do content.SetHeader("Content-Disposition",contentDisposition)

Request クラスを使用してプロセスの値を保持するため、Base64 コンテンツを、コンテンツのボディを構成するストリームに変換する必要があります。

StreamUtils ユーティリティを使用して、Base64 を Stream に変換できます。

注意: 「pImage」変数には、ファイルコンテンツの Base64 文字列が含まれます。

Do##class(HS.Util.StreamUtils).Base64Encode(pImage, .tStream)
Set content.Body = tStream

ただし、Global Summit 2023 において、幸運にも InterSystems エキスパートからもっと有用なコツを得られました。 実行は StreamUtils よりも高い効果があり、最終的には String と Stream のレコードを読み取るループがあることを教えていただきました。

これは、JSON を使用してそれを Stream に変換する Get を実行するだけの単純なソリューションです。

set contentfile = {}
set contentfile.file = pImage
set content.Body = contentfile.%Get("file",,"stream<base64")

呼び出しに必要なすべてのパラメーターを含めたら、ようやくパーツをエンクローズする新しい MIMEPart クラスを作成できます。

Set rootMIME = ##class(%Net.MIMEPart).%New()
do rootMIME.Parts.Insert(content)
set writer = ##class(%Net.MIMEWriter).%New()
set tSC = writer.OutputToStream(tHttpRequest.EntityBody)
set tSC = writer.WriteMIMEBody(rootMIME)
Set tContentType = "multipart/form-data; boundary="_rootMIME.Boundary
set tSC = ..Adapter.SendFormDataArray(.tHttpResponse, "POST", tHttpRequest,,,url)

このようにして、OpenAI で必要なメソッドにファイルコンテンツを送信します。

画像ファイル

Image メソッドでは、写真を送信してバリエーションを実行することができます。 すべてのイラストは PNG 形式である必要があるため、Base64 形式のファイルコンテンツを指定する場合、ファイル名はランダムに生成され、PNG 拡張子が付けられます。

以下は、写真の変更例です。

元の写真バリエーション

ご覧のように、プログラムは命令を独自に解釈しています。

会社ロゴは円形と判断して入れ替えています。 また、オフィスにはガラスのドアが使用されていることを認識し、別のガラスのドアに入れ替えて、この時点ではレンガの壁が適用されています。

さらに、シャツの色を変更し、男性の腕の位置も変わっています。

また、OpenAI ではプロンプトに示されたコンテンツを挿入する領域にマスクを指定することで、画像を編集できます。

同じ画像を使用して、画像の背景を取り除くマスクを適用しました。

元の写真マスク

OpenAI にジャマイカのビーチに転送してほしいと指示すると、以下のような結果になりました。

家族や友人に会うときに、自分の休暇を自慢できるようになりました 😊

Image

エンドポイント: POST https://api.openai.com/v1/images/variations

既存の画像を変更した画像を作成できます。 変更方法を指定するプロンプトは不要であるため、この画像の解釈方法については AI のセンスを信用する必要があります。 また、結果のサイズと、リンクまたは Base64 のコンテンツのどちらの戻し方を希望するかを定義できます。

入力パラメーターは以下のようになります。

  • image: 必須
  • 変換する画像ファイルを指定します。
  • n: オプション。 デフォルトは 1 です。
  • このエリアでは、生成する画像の最大数を指定します。 (1~10 の数値を使用します)。
  • size: オプション。 デフォルトは 1024x1024 です。
  • このパラメーターは生成される画像のサイズを特徴づけます。 値は “256x256”、“512x512”、または “1024x1024” です。
  • response_format: オプション。 デフォルトで “url” になります。
  • この要素は、生成された画像を戻す際の形式を指定します。 値は “url” または “b64_json” です。

エンドポイント: POST https://api.openai.com/v1/images/edits

マスク ファイルに基づいて既存の画像を変更し、プロンプトに従って画像を作成できます。 また、結果の寸法と、リンクまたは Base64 のコンテンツのどちらの戻し方を希望するかを指定できます。

入力パラメーターは以下のようになります。

  • image: 必須
  • 変更する画像ファイルを指定します。
  • mask: 必須
  • このパートでは、適用するマスク画像ファイルを指定します。
  • n: オプション。 デフォルトは 1 です。
  • このエリアでは、生成する画像の最大数を指定します。 (1~10 の数値を使用します)。
  • size: オプション。 デフォルトは 1024x1024 です。
  • このパラメーターは生成される画像のサイズを特徴づけます。 値は “256x256”、“512x512”、または “1024x1024” です。
  • response_format: オプション。 デフォルトで “url” になります。
  • この要素は、生成された画像を戻す際の形式を指定します。 値は “url” または “b64_json” です。

音声ファイル

OpenAI が管理するのは画像だけではありません。 音声ファイルを使用して、提供されたレコーディングのトランスクリプションまたは翻訳を取得することもできます。

このメソッドは、固有名詞、ブランド、およびスラングを区別して正しいトランス来居プションと翻訳を提供できる Whisper モデルを使用します。 たとえば、「micromachine」というブランドについて言及するのと、一般名詞の「micro machines」をスペイン語に翻訳するのは同じことではありません。

次の例は、80 年代の有名な広告のトランスクリプションです。

<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/zLP6oT3uqV8" width="640"></iframe>

Whisper にこの音声のトランスクリプションを作成する命令の結果は以下のようになります。

{
    "text": "This is the Micromachine Man presenting the most midget miniature motorcade of micromachines. 
Each one has dramatic details, terrific trim, precision paint jobs, plus incredible micromachine pocket playsets. 
There's a police station, fire station, restaurant, service station, and more. Perfect pocket portables to take anyplace. 
And there are many miniature playsets to play with and each one comes with its own special edition micromachine vehicle and 
fun fantastic features that miraculously move. Raise the boat lift at the airport, marina, man the gun turret at 
the army base, clean your car at the car wash, raise the toll bridge. And these playsets fit together to form a micromachine world.
Micromachine pocket playsets, so tremendously tiny, so perfectly precise, so dazzlingly detailed, you'll want to pocket them all.
Micromachines and micromachine pocket playsets sold separately from Galoob. The smaller they are, the better they are."
}

素晴らしいです! そう思いませんか?

上記の結果は、Whisper モデルが受けたトレーニングによって実現しています。 これに関する情報は、OpeanAI ページに記載されている以下のダイアグラムでご覧いただけます。

 

詳細は、https://openai.com/research/whisper をご覧ください。

サービスは処理するファイルのタイプ(WAV、MP3、OGG など)を知っておく必要があるため、ファイル名に関する情報をプログラムに提供することが重要であることに注意してください。

呼び出しには Base64 コンテンツのみを含めるため、ランダムなテキストと指定拡張子でファイル名を作成できるように、ファイル拡張子も指定する必要があります。

たとえば、St.OpenAi.Msg.Audio.AudioRequest メッセージには、音声の種類を示す MP3、OGG、WAV、FLAC などの “type” プロパティがあります。

エンドポイント: https://api.openai.com/v1/audio/transcriptions

このメソッドでは、音声のコンテンツを音声の言語に文字起こしできます。

入力パラメーターは以下のようになります。

  • file: 必須
  • 文字起こしする音声ファイル(ファイル名ではありません)を指定します。 次の形式がサポートされています: FLAC、MP3、MP4、MPEG、MPGA、M4A、OGG、WAV、または WEBM
  • model: 必須。
  • トランスクリプションを作成するのに使用するモデル。 現時点では、“whisper-1” のみを使用できます。
  • language: オプション。 デフォルトでは、音声の言語です。
  • ISO-639-1 によると、指定されている場合、精度とレイテンシーが改善されます。
  • prompt: オプション。
  • これは、モデルのスタイルをガイドするため、または前の音声セグメントを継続するためのオプションのテキストです。 このメッセージは音声の言語に一致している必要があります。
  • response_format。 オプション。 デフォルトで “json” になります。
  • このパートでは、トランスクリプション出力のフォーマットを明確にします。 “json”、“text”、“verbose_json” のいずれかのオプションを使用します。
  • temperature: オプション。 デフォルト値は 0 です。
  • サンプリング温度は 0~1 です。 0.8 のように値が高くなるほど出力がよりランダムになり、0.2 のように低くなるほど集中的で確定的になります。 0 に設定すると、モデルは対数尤度を使用して、特定のしきい値に達するまで温度を自動的に高めます。

このメソッドのドキュメントは https://platform.openai.com/docs/api-reference/audio/createTranscription<をご覧ください。

エンドポイント: https://api.openai.com/v1/audio/translations

このメソッドでは、音声のコンテンツを英語に翻訳できます。

入力パラメーターは以下のようになります。

  • file: 必須
  • 翻訳する音声ファイルです(ファイル名ではありません)。 次の形式がサポートされています: FLAC、MP3、MP4、MPEG、MPGA、M4A、OGG、WAV、または WEBM
  • model: 必須。
  • このフィールドには、トランスクリプションを作成するために使用するモデルを入力します。 現時点では、“whisper-1” のみを使用できます。
  • prompt: オプション。
  • これは、モデルのスタイルをガイドするため、または前の音声セグメントを継続するためのオプションのテキストです。 このメッセージは英語である必要があります。
  • response_format。 オプション。 デフォルトで “json” になります。
  • ここでは、トランスクリプションの出力の形式を “json”、“text”、“verbose_json” から指定します。
  • temperature: オプション。 デフォルト値は 0 です。
  • サンプリング温度は 0~1 です。 0.8 のように値が高くなるほど出力がよりランダムになり、0.2 のように低くなるほど集中的で確定的になります。 0 に設定すると、モデルは対数尤度を使用して、特定のしきい値に達するまで温度を自動的に高めます。

このメソッドのドキュメントは https://platform.openai.com/docs/api-reference/audio/createTranscriptionをご覧ください。

次の内容

OpenAI は継続的に進化しているため、次回の記事ではテキストから音声への変換方法とその他の新機能をいくつか紹介します。

記事を気に入っていただけたなら、「いいね」を押してください。

0
0 131
記事 Toshihiko Minamoto · 4月 4, 2024 10m read

 

皆さんもご存知のように、人工知能の世界はもう生活の中に存在しており、誰もが利用従っています。

多数のプラットフォームが、無料、サブスクリプション、または非公開の形式で、人工知能サービスを提供していますが、 コンピューティングの世界で「話題」となったことから、特に注目されているサービスは OpenAI です。最も有名な ChatGPT および DALL-E が主な原因と言えます。

<--break->OpenAI とは?

OpenAI は、人類全体にメリットのあるフレンドリーな人工知能の促進と開発を目指して、Sam Altman、Ilya Sutskever、Greg Brockman、Wojciech Zaremba、Elon Musk、John Schulman、および Andrej Karpathy によって 2015 年に設立された非営利の AI 研究所です。

設立以来、適切な目的のために使用されれば非常に強力なツールとなりうる素晴らしい製品をいくつかリリースしてきました。 とは言え、ほかのどの新しいテクノロジーと同様に、犯罪や悪行に使用される可能性があるという脅威があります。

そこで、ChatGPT サービスをテストして人工知能の定義が何かを尋ねてみました。 受け取った回答は、インターネット上で見つかった概念を蓄積して人間が回答するような方法で要約したものでした。

つまり、AI はそれをトレーニングするために使用された情報を使ってでしか返答できないということです。 内部アルゴリズムとトレーニング中に流入したデータを使用することで、記事、詩、さらにはコンピューターのコードまで作成することができます。

人工知能は、業界に大々的な影響を与え、最終的にはすべてに革命を起こすことでしょう…。 おそらく、人工知能が私たちの未来にどのように影響するのかという期待は誇示されており、公共の利益のために、それを正しく使用し始めなければなりません。

この新しいテクノロジーがすべてを変え、ChatGPT がその兄弟の GPT-4 のように私たちの世界を逆さにするという話に聞き飽きています。 どのツールも人間から仕事を奪うこともなければ、(スカイネットのように)世界を支配するようなこともありません。 ここで分析しようとしているのは、トレンドです。 これまでに達成したことを理解するために、以前の状況を振り返ることから始め、それによって自分たちの未来の状況を予測しています。

2020 年、心理学者であり認知科学者でもある Gary Marcus が GPT-2 がどのように機能したかを分析した記事を公開しました。 その動作に関する系統的な研究を実施し、そのタイプのツールが実際に何を書いているのか、どのような命令を受け取っているのかを理解できていないことを明らかにしました。

「問題はこれです。慎重に検査すると、システムはそれ自体が話していることについて見当がついていないことが明らかになります。単純なイベントの順序をたどることもできなければ、次に何が起きる可能性があるかについて確実な見当も得られないのです。」

以下のリンクで、記事全体をご覧いただけます: https://thegradient.pub/gpt2-and-the-nature-of-intelligence/

ここで、明白に進化をみることができます! GPT-3(2020 年)は、達成したいことを示した十分な入力を使ってトレーニングする必要がありましたが、現行の GPT-4 バージョンでは自然言語を使用することができるため、入力をより簡単に提供することができます。 これで、命令の意図を理解するだけでなく、それ自体が話している内容を理解している「ように見えます」。

現在は、Gary Marcus が 2020 年に GPT-2 用に作成した同じ例を使用した場合、期待どおりの結果を得られます。

OpenAI は現在、驚くほどの速さで大幅に進化した一連のツールを提供しており、適切に組み合わせれば、以前よりも効率的な結果をはるかに簡単に得ることができます。

OpenAI が提供する製品

最もよく知られた 2 つの製品について話したいと思います。DALL-E と ChatGPT です。 ただし、OpenAI には他にも、音声をテキストに書き起こし、別の言語への翻訳も行える Whisper や、検索、推奨、グループ化などの操作においてテキスト文字列の関係を測定できる Embeddings などのサービスも提供しています。

これらのサービスを使用するために必要なもの

OpenAI アカウントの作成が必要です。作成方法は非常に簡単であり、作成すれば、直接 OpenAI のウェブサイトを通じてサービスを使用できるようになります。

Chat: https://chat.openai.com

DALL-E: https://labs.openai.com

これらのサービスを IRIS から統合するので、その API を使用してアクセスする必要があります。 まず、アカウントを作成し、API を使用できるように支払方法を指定する必要があります。 費用は比較的低いですが、使用内容によってことなります。 トークンを多く消費するほど、費用が高くなります 😉

トークンとは?

モデルがテキストを理解して処理するために使用する手段です。 トークンは語または単なる文字の断片です。 たとえば、「hamburger」という語は、「ham」、「bur」、「ger」というタイルに分離されるのに対し、「pear」のような短い語は 1 つのタイルになります。 多くのトークンは「 hello」や「 bye」のように空のスペースで始まります。

API の使用は複雑ですか?

まったく複雑ではありません。 以下の手順に従えば、問題はありません。

ステップ 1: API キーの作成

ユーザーのメニューにある「View API Key」オプションを選択します。

 

ステップ 2: 新しいシークレットキーの作成

API Keys のセクションの下にあるボタンを押します。

 

非常に重要: シークレットキーが作成されると、どのような場合でも復元はできないため、安全な場所に情報を保存してください。

ステップ 3: 組織の名前の定義

組織の定義は必須ではありませんが、推奨されます。 API 呼び出しのヘッダーの一部となります。 また、組織のコードを後で使用できるようにコピーしておく必要もあります。

 これは、必要に応じて何度でも変更できます。

ステップ 4: シークレットキーと組織 ID による API 呼び出しの準備

API 呼び出しの一部として、ベアラートークン認証ヘッダーを使用し、シークレットキーを指定する必要があります。

組織 ID の横にヘッダーパラメーターとして指定されていることも必要です。

ヘッダーパラメーター
api-keysk-MyPersonalSecretKey12345
OpenAI-Organizationorg-123ABCFakeId

以下は呼び出しの例です。

POST https://api.openai.com/v1/images/create
header 'Authorization: Bearer sk-MyPersonalSecretKey12345'
header 'api-key: sk-MyPersonalSecretKey12345'
header 'OpenAI-Organization: org-123ABCFakeId '
header 'Content-Type: application/json'

この構成はすべてのエンドポイントに共通であるため、最もよく知られたメソッドがどのように機能するか見てみましょう。

Models

エンドポイント: GET https://api.openai.com/v1/models

OpenAI が使用できるように定義したすべてのモデルをダウンロードできます。 ただし、モデルごとに特徴が異なります。 Chat で使用する最新のモデルは「gpt-4」です。 すべてのモデルの ID は小文字表記であることに注意してください。

モデル名が指定されていない場合は、既存のモデルがすべて返されます。

機能と使用場所は、OpenAI ドキュメントページ(https://platform.openai.com/docs/models/overview)をご覧ください。

Chat

エンドポイント: POST https://api.openai.com/v1/chat/completions

指定されたモデルを使って、または通知を介して、会話を作成できます。 最大いくつのトークンを使用するのか、会話をいつ止めるのかを指定できます。

入力パラメーターは以下のようになります。

  • model: 必須。 これは、使用するモデルの ID です。 ListModels API を使用すると、使用できるモデルをすべて確認したり、モデルの概要で説明を確認したりできます。
  • messages: 必須。 どの役割を使用するかを示したメッセージのタイプを含みます。 ユーザーであるかアシスタントであるかを指定して、ダイアログフォームを定義できます。
    • role: メッセージの人のロールです。
    • content: メッセージのコンテンツです。
  • temperature: オプション。 示される温度を 0~2 の値で示します。 数値が高いほど、よりランダムな結果になります。 数値が低いほど、回答はより集中的で確定的になります。 定義されていない場合、デフォルト値は 1 です。
  • stop: オプション。 API がトークンを生成しなくなるシーケンスに関連しています。 「none」が指定されている場合、トークンは無限に生成されます。
  • max_tokens: オプション。 コンテンツを生成するトークンの最大数を指定し、モデルが許可する最大トークン数に制限されます。

このメソッドを説明するドキュメントは、以下のリンクをご覧ください: https://platform.openai.com/docs/api-reference/chat/create

Image

エンドポイント: POST https://api.openai.com/v1/images/generations

プロンプトパラメーターで指定されたとおりに画像を作成できます。 また、結果のサイズと、リンクまたは Base64 のコンテンツのどちらの戻し方を希望するかを定義できます。

入力パラメーターは以下のようになります。

  • message: 必須。 生成する画像を説明するテキストに関連しています。
  • n: オプション。 生成する画像の最大数に関連しています。 これは 1~10 の値です。 指定されていない場合、デフォルト値は 1 です。
  • size: オプション。 生成される画像のサイズに関連しています。 値は "256x256"、"512x512"、または "1024x1024" です。 指定されていない場合、デフォルト値は "1024x1024" です。
  • response_format: オプション。 生成された画像を戻す際の形式に関連しています。 値は "url" または "b64_json" です。 指定されていない場合、デフォルト値は "url" です。

このメソッドを説明するドキュメントは、以下のリンクをご覧ください: https://platform.openai.com/docs/api-reference/images/create

iris-openai とは?

リンク: https://openexchange.intersystems.com/package/iris-openai

このフレームワークは、必要なプロパティを含むリクエストおよびレスポンスメッセージを使用して OpenAI に接続し、Chat、Models、Images などのメソッドを使用できるように設計されています。

本番環境は、メッセージングクラスを使用して、OpenAI API に接続するビジネスオペレーションを呼び出せるように構成できます。

前述のとおり、シークレットキーと組織 ID の値を指定して本番環境を構成する必要があることに注意してください。

 

画像を作成する場合、クラスインスタンス "St.OpenAi.Msg.Images.ImagesRequest" を生成して、新しい写真を作成するためのオプションの値を入力する必要があります。

例:

Set image=##class(St.OpenAi.Msg.Images.ImagesRequest).%New()
Set image.Operation = "generations"Set image.Prompt = "Two cats with a hat reading a comic"Set image.NumOfImages = 2

完了したら、"St.OpenAi.BO.Api.Connect" ビジネスオペレーションを呼び出します。

 

注意: この場合、作成された 2 つの画像のリンクが取得されます。

{
    "created": 1683482604,
    "data": [
        {
            "url": "https://link_of_image_01.png”
        },
        {
            "url": "https://link_of_image_02.png”
        }
    ]
}

リンクではなく Base64 を操作すると指定されている場合、以下のメッセージが取得されます。

{
    "created": 1683482604,
    "data": [
        {
            "b64_json": "iVBORw0KGgoAAAANSUhEUgAABAAAAAQACAIAAADwf7zUAAAAaGVYSWZNTQAqAAAACAACknwAAgAAACkAAAAmkoYAAgAAABgAAABQAAAAAE9wZW5BSS0tZjM5NTgwMmMzNTZiZjNkMDFjMzczOGM2OTAxYWJiNzUAAE1hZGUgd2l0aCBPcGVuQUkgREFMTC1FAAjcEcwAAQAASURBVHgBAAuE9HsBs74g/wHtAAL7AAP6AP8E+/z/BQYAAQH++vz+CQcH+fn+AgMBAwQAAPr++///AwD+BgYGAAIC/fz9//3+AAL7AwEF/wL+9/j9DQ0O/vz/+ff0CQUJAQQF/f/89fj4BwcD/wEAAfv//f4BAQQDAQH9AgIA/f3+AAABAgAA/wH8Af/9AQMGAQIBAvv+/////v/+/wEA/wEAAgMA//sCBAYCAQ”
        },
        {
            "b64_json": "D99vf7BwcI/v0A/vz9/wH8CQcI+vz8AQL9/vv+CAcF+wH/AwMA9/f8BwUEAwEB9fT+BAcKBAIB//7//gX5//v8/P7+DgkO+fr6/wD8AP8B/wAC/f4CAwD+/wT+Av79BwcE/Pz7+/sBAAD+AAQE//8BAP79AgIE///+AQABAv8BAwYA+vkB/v7/AwQE//7+/Pr6BAYCBgkE/f0B/Pr6AQP+BAED/gMC/fr+AwEC/v/+//7+CQcH+fz5BAYB9vf9BgQD+/n+BwYK/wD////9/gD5AwIDAAQE+/j6BAUD//rwAC/fr6+wYEBAQAA/4B//v6+/8AAAUDB/L49woGAQMDCfr7+wMCAQMHBPvy+AQJBQD+/wEEAfr3+gIGBgP/Af3++gUFAvz9//4A/wP/AQIGBPz+/QD7/wEDAgkGCPX29wMCAP4FBwX/+23"
        }
    ]
}

次の内容

この記事の公開後、iris-openai のコンテンツが拡張され、Whisper メソッドと画像変更に使用できるようになっているでしょう。

以降の記事では、これらのメソッドの使用方法と画像を含める方法、または音声コンテンツのトランスクリプションの作成方法を説明します。

0
0 237
記事 Toshihiko Minamoto · 8月 7, 2023 7m read

この記事では、.Net/Java ゲートウェイを簡単にコンテナ化する方法を説明します。

この例では、Apache Kafka との統合を開発します。

Java/.Net と相互運用するために、PEX を使用しています。

アーキテクチャ

このソリューションは完全に docker で実行し、以下のように構成されます。

Java ゲートウェイ

まず、メッセージを Kafka に送信する Java オペレーションを開発しましょう。 このコードはお好きな IDE で書くことができ、こちらのようになります。

要約すると:

  • 新しい PEX ビジネスオペレーションを開発するには、抽象型の com.intersystems.enslib.pex.BusinessOperation クラスを実装する必要があります。
  • public プロパティはビジネスホスト設定です。
  • OnInit メソッドは Kafka への接続を初期化し、InterSystems IRIS へのポインターを取得するために使用されます。
  • OnTearDown は、(プロセスのシャットダウン時に)Kafka から切断するために使用されます。
  • OnMessagedc.KafkaRequest メッセージを受け取って、Kafka に送信します。

では、これを Docker にパックしましょう!

これがこの例の dockerfile です。

FROM eclipse-temurin:8-jre-alpine AS builder

ARG APP_HOME=/tmp/app

COPY src $APP_HOME/src

COPY --from=intersystemscommunity/jgw:latest /jgw/*.jar $APP_HOME/jgw/

WORKDIR $APP_HOME/jar/
ADD https://repo1.maven.org/maven2/org/apache/kafka/kafka-clients/2.5.0/kafka-clients-2.5.0.jar .
ADD https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar .
ADD https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar .
ADD https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar .

WORKDIR $APP_HOME/src

RUN javac -classpath $APP_HOME/jar/*:$APP_HOME/jgw/* dc/rmq/KafkaOperation.java && \
    jar -cvf $APP_HOME/jar/KafkaOperation.jar dc/rmq/KafkaOperation.class

FROM intersystemscommunity/jgw:latest

COPY --from=builder /tmp/app/jar/*.jar $GWDIR/

1 行ずつ見ながら、ここに何が起きているのかを確認しましょう(マルチステージ docker ビルドを理解していることが前提です)。

FROM eclipse-temurin:8-jre-alpine AS builder

最初のイメージは JDK 8 です(openjdk:8 イメージは廃止されたことに注意してください。代わりに推奨されているものを使用します)。

ARG APP_HOME=/tmp/app
COPY src $APP_HOME/src

/src フォルダから /tmp/app フォルダにソースをコピーしています。

COPY --from=intersystemscommunity/jgw:latest /jgw/*.jar $APP_HOME/jgw/

Java ゲートウェイソースを /tmp/app/jgw フォルダにコピーしています。

WORKDIR $APP_HOME/jar/
ADD https://repo1.maven.org/maven2/org/apache/kafka/kafka-clients/2.5.0/kafka-clients-2.5.0.jar .
ADD https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar .
ADD https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar .
ADD https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar .

WORKDIR $APP_HOME/src

RUN javac -classpath $APP_HOME/jar/*:$APP_HOME/jgw/* dc/rmq/KafkaOperation.java && \
    jar -cvf $APP_HOME/jar/KafkaOperation.jar dc/rmq/KafkaOperation.class

これですべての依存関係が追加され、jar ファイルのコンパイルに javac/jar が呼び出されます。 実際のプロジェクトでは、Maven または Gradle の使用をお勧めします。

FROM intersystemscommunity/jgw:latest

COPY --from=builder /tmp/app/jar/*.jar $GWDIR/

そして最後に、jar がベース jgw イメージにコピーされます(ベースイメージは、ゲートウェイと関連タスクの開始も処理します)。

.Net ゲートウェイ

次は、Kafka からメッセージを受け取る .Net サービスです。 このコードはお好きな IDE で書くことができ、こちらのようになります。

要約すると:

  • 新しい PEX ビジネスサービスを開発するには、抽象型の InterSystems.EnsLib.PEX.BusinessService クラスを実装する必要があります。
  • public プロパティはビジネスホスト設定です。
  • OnInit メソッドは Kafka への接続を初期化し、トピックを購読し、InterSystems IRIS へのポインターを取得するために使用されます。
  • OnTearDown は、(プロセスのシャットダウン時に)Kafka から切断するために使用されます。
  • OnMessage は Kafka からのメッセージを入力として使用し、他の相互運用性ホストに Ens.StringContainer メッセージを送信します。

では、これを Docker にパックしましょう!

これがこの例の dockerfile です。

FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build

ENV ISC_PACKAGE_INSTALLDIR /usr/irissys
ENV GWLIBDIR lib
ENV ISC_LIBDIR ${ISC_PACKAGE_INSTALLDIR}/dev/dotnet/bin/Core21

WORKDIR /source
COPY --from=store/intersystems/iris-community:2020.2.0.211.0 $ISC_LIBDIR/*.nupkg $GWLIBDIR/

# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# copy and publish app and libraries
COPY . .
RUN dotnet publish -c release -o /app

# final stage/image
FROM mcr.microsoft.com/dotnet/core/runtime:2.1
WORKDIR /app
COPY --from=build /app ./

# Configs to start the Gateway Server
RUN cp KafkaConsumer.runtimeconfig.json IRISGatewayCore21.runtimeconfig.json && \
    cp KafkaConsumer.deps.json IRISGatewayCore21.deps.json

ENV PORT 55556

CMD dotnet IRISGatewayCore21.dll $PORT 0.0.0.0

1 行ずつ見ていきましょう。

FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build

このアプリの構築には、完全な .Net Core 2.1 SDK を使用します。

ENV ISC_PACKAGE_INSTALLDIR /usr/irissys
ENV GWLIBDIR lib
ENV ISC_LIBDIR ${ISC_PACKAGE_INSTALLDIR}/dev/dotnet/bin/Core21

WORKDIR /source
COPY --from=store/intersystems/iris-community:2020.2.0.211.0 $ISC_LIBDIR/*.nupkg $GWLIBDIR/

正式な InterSystems Docker イメージから .Net Gateway NuGets をビルダーイメージにコピーします。

# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# copy and publish app and libraries
COPY . .
RUN dotnet publish -c release -o /app

ライブラリを構築します。

# final stage/image
FROM mcr.microsoft.com/dotnet/core/runtime:2.1
WORKDIR /app
COPY --from=build /app ./

ライブラリ dll を、実際に実行する最終コンテナにコピーします。

# Configs to start the Gateway Server
RUN cp KafkaConsumer.runtimeconfig.json IRISGatewayCore21.runtimeconfig.json && \
    cp KafkaConsumer.deps.json IRISGatewayCore21.deps.json

現在、.Net ゲートウェイは起動時にすべての依存関係を読み込む必要があるため、考えられるすべての依存関係を認識するようにしています。

ENV PORT 55556

CMD dotnet IRISGatewayCore21.dll $PORT 0.0.0.0

すべてのインターフェースでリッスンするポート 55556 でゲートウェイを開始します。

以上です!

こちらは、すべてをまとめて実行する完全な docker-compose です(Kafka とメッセージを見るための Kafka UI も含まれています)。

このデモを実行するには、以下を行う必要があります。

  1. インストール:
  2. 実行:
git clone https://github.com/intersystems-community/pex-demo.git cd pex-demo docker-compose pull docker-compose up -d

 

注意事項: Java ゲートウェイと .Net ゲートウェイライブラリは、InterSystems IRIS クライアントと同じバージョンのものである必要があります。

0
0 189
記事 Mihoko Iijima · 6月 1, 2023 7m read

開発者の皆さん、こんにちは。

先日のウェビナーでご紹介した「ワークフローコンポーネント」をお試しいただけるサンプルを公開しました。👉 https://github.com/Intersystems-jp/WorkFlow-DC

《サンプルのテーマ》

店舗で販売している商品に付けるPOPメッセージ候補を予めテーブルに登録できる仕組みが既にある、と仮定しています。

IRISの Interoperability を利用してPOPメッセージ候補が登録されるテーブルに対して一定間隔でSELECT文を実行し、未処理のメッセージを取得します。
新たなレコードが存在する場合、ワークフローコンポーネントを利用して担当者に審査を依頼します。

担当者は、ワークフローユーザポータルを使用して、POPメッセージ候補の承認/却下を指示できるようにしています。

0
0 206
記事 Toshihiko Minamoto · 12月 15, 2021 2m read

あるお客様の問題から、この短い記事を書くことにしました。 お客様はEnsembleを使用して、多数のシステムを統合しています。一部のシステムではプレーンファイルのみが使用されています。

そのため、ターゲットファイルへの書き込みには、自然とFile Outbound Adapter を選択しました。 数年もの間すべてが順調に稼働していましたが、最近になって、ファイルに書き込まれるデータが数十メガバイトという大きなサイズに達するようになり問題が出てきました。オペレーションが完了するまでに約30分かかるようになり、プロセス内の後続の処理を待たせなければならないタイミングの問題が発生し始めたのです。当然、連携先のシステムはそれほど長く待つことを良しとしません。

お客様のコードは、以下の疑似コードのようなものでした。

 set tResultSet=SQLStatement.Execute()

 // compose header based on resultset columns Describe()

 set tSC= ..Adapter.PutLine(file,header)

while tResultSet.%Next() {

 set line=... compose line of the resultset row data 

  set tSC=..Adapter.PutLine(file,line)

}

アダプターのPutLine() メソッドのソースコードを見ると、このメソッドがファイルを開き、行を書き込んで、ファイルを閉じていることがわかりました。 しかも、行ごとにです!!!

そこで、より良いアダプターAPIを提供できないか確認したところ、PutStream() メソッドというのを見つけました。 大当たりです!これが正しいメソッドで、ストリームを毎回開かずに、ただ書き込むメソッドです。

コードを以下のように書き換えました。

set tTmpStream=##class(%FileCharacterStream).%New()

set tResultSet=SQLStatement.Execute()

 // compose header based on resultset columns Describe()

 set tSC= ..tTmpStream.WriteLine(header)

while tResultSet.%Next() {

 set line=... compose line of the resultset row data 

 set tSC=tTmpStream.WriteLine(line)

}

set tSC=..Adapter.PutStream(file,tTmpStream)

 

お客様は上記の変更したコードを使用して、オペレーションを再実行しました。 これで、オペレーションにかかる時間は数秒になりました!

結果: ファイルを処理する場合、PutLine() が最初の(そして最も簡単な)選択肢かもしれませんが、本番環境では必ずしも良い方法とは言えません。特に大きなファイルを取り扱う場合は尚更です。

今後の開発プロジェクトのお役に立てられれば幸いです。

Dan Kutac

0
0 125
記事 Toshihiko Minamoto · 11月 9, 2021 18m read

IRISインターオペラビリティのメッセージビューワで何かを変更できるとしたら、何を変更しますか?

Dashboard IRIS History Monitor」の記事を公開したところ、素晴らしいフィードバックやリクエストをいただきました。 中には、メッセージビューワの拡張に関するリクエストがありました。
 

まだプロジェクトを確認していない方は、ぜひご覧ください。絶対に見る価値がありますし、2019年の最高のInterSystems Open Exchange開発者およびアプリケーションの1つとしてブロンズ賞を受賞しました。

「新しい」メッセージビューワに含めようと思う機能についてのアイデアを書き留め始めましたが、これらのリソースをどのようにすれば素早く簡単に見せることができるのでしょうか。

まずは、 一般的に、相互運用性の本番環境をセットアップし、ドキュメントの指示のとおりに、ターゲットシステムにエクスポートしてデプロイすることから始めます。 これは私があまり好まないプロセスです。 特に何か悪いというわけではありませんが、 コードを使ってすべてを行う考えがあるためです。

誰かがこういったプロジェクトを実行するたびに、次のように開始することを期待しています。

$ docker-compose build

$ docker-compose up -d

いかがでしょうか!!!

たったこれだけのステップを思い浮かべながら、InterSystemsコミュニティを調べ始めると、いくつかのヒントが見つかりました。 ある投稿では、私が自問していた質問が挙げられていました。「ルーチンを使って本番環境を作成するにはどうすればよいのか。

その投稿の中で、@Eduard Lebedyuk が、コードを使って本番環境を作成する方法を次のように回答しています。

「本番クラスを自動的に作成するには、次を行う必要があります。

  1. テストプロダクション用の%Dictionary.ClassDefinitionオブジェクトを作成します。
  2. Ens.Config.Productionオブジェクトを作成します。
  3. %Dictionary.XDataDefinitionを作成します。
  4. (2) を (3) にシリアル化します。
  5. XData (3) を (1) に挿入します。
  6. (1) を保存してコンパイルします。」

@Jenny Amesのコメントにも、次のように書かれていました。

 「私たちがよくお勧めしているベストプラクティスは、逆方向に構築することです。 ビジネスオペレーションを先に構築してから、ビジネスプロセス、そしてビジネスサービスを構築していく方法です...」

というわけで、早速やってみましょう!

リクエスト、ビジネスオペレーション、およびビジネスサービス

クラスdiashenrique.messageviewer.util.InstallerProduction.clsは、名前から想像できるように、プロダクションのインストールを担当するクラスです。 インストーラのマニフェストは、そのクラスからClassMethod Installを呼び出します。

/// 拡張ビューワの表示機能にプロダクションをインストールするヘルパー

ClassMethod Install() As %Status

{

    Set sc = $$$OK

    Try {

        Set sc = $$$ADDSC(sc,..InstallProduction()) quit:$$$ISERR(sc)

        Set sc = $$$ADDSC(sc,..GenerateMessages()) quit:$$$ISERR(sc)

        Set sc = $$$ADDSC(sc,..GenerateUsingEnsDirector()) quit:$$$ISERR(sc)

    }

    Catch (err) {

        Set sc = $$$ADDSC(sc,err.AsStatus())

    }

    Return sc

}

クラスメソッドInstallProductionは、次を作成することで、プロダクションを作成するためのメインの構造をまとめます。

  • リクエスト
  • ビジネスオペレーション
  • ビジネスサービス
  • 相互運用性プロダクション

コードを使用して相互運用性プロダクションを作成しようと考えているため、完全なコーディングモードに移行して、リクエスト、ビジネスオペレーション、およびビジネスサービスの全クラスを作成しましょう。 これを行うには、いくつかのInterSystemsライブラリパッケージを広範に使用します。

  • %Dictionary.ClassDefinition
  • %Dictionary.PropertyDefinition
  • %Dictionary.XDataDefinition
  • %Dictionary.MethodDefinition
  • %Dictionary.ParameterDefinition

クラスメソッドInstallProductionは、次のコードを使用して、Ens.Requestを継承した2つのクラスを作成します。

Set sc = $$$ADDSC(sc,..CreateRequest("diashenrique.messageviewer.Message.SimpleRequest","Message")) quit:$$$ISERR(sc)

Set sc = $$$ADDSC(sc,..CreateRequest("diashenrique.messageviewer.Message.AnotherRequest","Something")) quit:$$$ISERR(sc)

ClassMethod CreateRequest(classname As %String, prop As %String) As %Status [ Private ]

{

    New $Namespace

    Set $Namespace = ..#NAMESPACE

    Set sc = $$$OK

    Try {

        Set class = ##class(%Dictionary.ClassDefinition).%New(classname)

        Set class.GeneratedBy = $ClassName()

        Set class.Super = "Ens.Request"

        Set class.ProcedureBlock = 1

        Set class.Inheritance = "left"

        Set sc = $$$ADDSC(sc,class.%Save())

        #; create adapter

        Set property = ##class(%Dictionary.PropertyDefinition).%New(classname)

        Set property.Name = prop

        Set property.Type = "%String"

        Set sc = $$$ADDSC(sc,property.%Save())

        Set sc = $$$ADDSC(sc,$System.OBJ.Compile(classname,"fck-dv"))

    }

    Catch (err) {

        Set sc = $$$ADDSC(sc,err.AsStatus())

    }

    Return sc

}

 

では、Ens.BusinessOperationを継承したビジネスオペレーションのクラスを作成しましょう。

Set sc = $$$ADDSC(sc,..CreateOperation()) quit:$$$ISERR(sc)

このクラスを作成するほかに、MessageMapとメソッドConsumeを作成します。

ClassMethod CreateOperation() As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
        Set classname = "diashenrique.messageviewer.Operation.Consumer"
        Set class = ##class(%Dictionary.ClassDefinition).%New(classname)
        Set class.GeneratedBy = $ClassName()
        Set class.Super = "Ens.BusinessOperation"
        Set class.ProcedureBlock = 1
        Set class.Inheritance = "left"
 
        Set xdata = ##class(%Dictionary.XDataDefinition).%New()
        Set xdata.Name = "MessageMap"
        Set xdata.XMLNamespace = "http://www.intersystems.com/urlmap"
        Do xdata.Data.WriteLine("<MapItems>")
        Do xdata.Data.WriteLine("<MapItem MessageType=""diashenrique.messageviewer.Message.SimpleRequest"">")
        Do xdata.Data.WriteLine("<Method>Consume</Method>")
        Do xdata.Data.WriteLine("</MapItem>")
        Do xdata.Data.WriteLine("<MapItem MessageType=""diashenrique.messageviewer.Message.AnotherRequest"">")
        Do xdata.Data.WriteLine("<Method>Consume</Method>")
        Do xdata.Data.WriteLine("</MapItem>")
        Do xdata.Data.WriteLine("</MapItems>")      
        Do class.XDatas.Insert(xdata)
        Set sc = $$$ADDSC(sc,class.%Save())
 
        Set method = ##class(%Dictionary.MethodDefinition).%New(classname)
        Set method.Name = "Consume"
        Set method.ClassMethod = 0
        Set method.ReturnType = "%Status"
        Set method.FormalSpec = "input:diashenrique.messageviewer.Message.SimpleRequest,&output:Ens.Response"
        Set stream = ##class(%Stream.TmpCharacter).%New()
        Do stream.WriteLine("   set sc = $$$OK")
        Do stream.WriteLine("   $$$TRACE(input.Message)")
        Do stream.WriteLine("   return sc")
        Set method.Implementation = stream
        Set sc = $$$ADDSC(sc,method.%Save())
 
        Set sc = $$$ADDSC(sc,$System.OBJ.Compile(classname,"fck-dv"))
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}

相互運用性プロダクションを作成する直前のステップでは、ビジネスサービスクラスを作成しましょう。

Set sc = $$$ADDSC(sc,..CreateRESTService()) quit:$$$ISERR(sc)

このクラスにはHttpリクエストを受信するためのUrlMapとRoutesがあります。

ClassMethod CreateRESTService() As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
        Set classname = "diashenrique.messageviewer.Service.REST"
        Set class = ##class(%Dictionary.ClassDefinition).%New(classname)
        Set class.GeneratedBy = $ClassName()
        Set class.Super = "EnsLib.REST.Service, Ens.BusinessService"
        Set class.ProcedureBlock = 1
        Set class.Inheritance = "left"
 
        Set xdata = ##class(%Dictionary.XDataDefinition).%New()
        Set xdata.Name = "UrlMap"
        Set xdata.XMLNamespace = "http://www.intersystems.com/urlmap"
        Do xdata.Data.WriteLine("<Routes>")
        Do xdata.Data.WriteLine("<Route Url=""/send/message"" Method=""POST"" Call=""SendMessage""/>")
        Do xdata.Data.WriteLine("<Route Url=""/send/something"" Method=""POST"" Call=""SendSomething""/>")
        Do xdata.Data.WriteLine("</Routes>")
        Do class.XDatas.Insert(xdata)
        Set sc = $$$ADDSC(sc,class.%Save())
 
        #; create adapter
        Set adapter = ##class(%Dictionary.ParameterDefinition).%New(classname)
        Set class.GeneratedBy = $ClassName()
        Set adapter.Name = "ADAPTER"
        Set adapter.SequenceNumber = 1
        Set adapter.Default = "EnsLib.HTTP.InboundAdapter"
        Set sc = $$$ADDSC(sc,adapter.%Save())
 
        #; add prefix
        Set prefix = ##class(%Dictionary.ParameterDefinition).%New(classname)
        Set prefix.Name = "EnsServicePrefix"
        Set prefix.SequenceNumber = 2
        Set prefix.Default = "|demoiris"
        Set sc = $$$ADDSC(sc,prefix.%Save())
 
        Set method = ##class(%Dictionary.MethodDefinition).%New(classname)
        Set method.Name = "SendMessage"
        Set method.ClassMethod = 0
        Set method.ReturnType = "%Status"
        Set method.FormalSpec = "input:%Library.AbstractStream,&output:%Stream.Object"
        Set stream = ##class(%Stream.TmpCharacter).%New()
        Do stream.WriteLine("   set sc = $$$OK")
        Do stream.WriteLine("   set request = ##class(diashenrique.messageviewer.Message.SimpleRequest).%New()")
        Do stream.WriteLine("   set data = {}.%FromJSON(input)")
        Do stream.WriteLine("   set request.Message = data.Message")
        Do stream.WriteLine("   set sc = $$$ADDSC(sc,..SendRequestSync(""diashenrique.messageviewer.Operation.Consumer"",request,.response))")
        Do stream.WriteLine("   return sc")
        Set method.Implementation = stream
        Set sc = $$$ADDSC(sc,method.%Save())
 
        Set method = ##class(%Dictionary.MethodDefinition).%New(classname)
        Set method.Name = "SendSomething"
        Set method.ClassMethod = 0
        Set method.ReturnType = "%Status"
        Set method.FormalSpec = "input:%Library.AbstractStream,&output:%Stream.Object"
        Set stream = ##class(%Stream.TmpCharacter).%New()
        Do stream.WriteLine("   set sc = $$$OK")
        Do stream.WriteLine("   set request = ##class(diashenrique.messageviewer.Message.AnotherRequest).%New()")
        Do stream.WriteLine("   set data = {}.%FromJSON(input)")
        Do stream.WriteLine("   set request.Something = data.Something")
        Do stream.WriteLine("   set sc = $$$ADDSC(sc,..SendRequestSync(""diashenrique.messageviewer.Operation.Consumer"",request,.response))")
        Do stream.WriteLine("   return sc")
        Set method.Implementation = stream
        Set sc = $$$ADDSC(sc,method.%Save())
 
        Set sc = $$$ADDSC(sc,$System.OBJ.Compile(classname,"fck-dv"))
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}

 

Visual Studioコードの使用

%Dictionaryパッケージを使用してクラスを作成するのは困難な場合があり、読みにくくもありますが、非常に便利です。 コードの可読性を良くしてアプローチをもう少しわかりやすくするために、Visual Studioコードを使用して新しいリクエスト、ビジネスサービス、およびビジネスオペレーションクラスを作成することにします。

  • diashenrique.messageviewer.Message.SimpleMessage.cls
  • diashenrique.messageviewer.Operation.ConsumeMessageClass.cls
  • diashenrique.messageviewer.Service.SendMessage.cls
    Class diashenrique.messageviewer.Message.SimpleMessage Extends Ens.Request [ Inheritance = left, ProcedureBlock ]
    {
     Property ClassMessage As %String; 
    }
     
    Class diashenrique.messageviewer.Operation.ConsumeMessageClass Extends Ens.BusinessOperation [ Inheritance = left, ProcedureBlock ]
    {
     Method Consume(input As diashenrique.messageviewer.Message.SimpleMessage, ByRef output As Ens.Response) As %Status
    { 
        Set sc = $$$OK
        $$$TRACE(pRequest.ClassMessage)
        Return sc
    }
    XData MessageMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
    {
       
         
           Consume
         
       
     }
    }
    
    Class diashenrique.messageviewer.Service.SendMessage Extends Ens.BusinessService [ ProcedureBlock ]
    { 
    Method OnProcessInput(input As %Library.AbstractStream, ByRef output As %Stream.Object) As %Status
    {
        Set tSC = $$$OK
        // リクエストメッセージを作成
        Set request = ##class(diashenrique.messageviewer.Message.SimpleMessage).%New()
        // リクエストメッセージプロパティに値をセット
        Set request.ClassMessage = input
        // ビジネスプロセスに同期呼び出しを行い、レスポンスメッセージをレスポンスとして使用 
        Set tSC = ..SendRequestSync("diashenrique.messageviewer.Operation.ConsumeMessageClass",request,.output)
        Quit tSC
    }
    }

コードの可読性の観点では、大きな差があります! 

相互運用性プロダクションの作成

相互運用性プロダクションを仕上げましょう。 これを行うには、プロダクションクラスを作成してから、それをビジネスオペレーションとサービスクラスに関連付けます。

Set sc = $$$ADDSC(sc,..CreateProduction()) quit:$$$ISERR(sc)

ClassMethod CreateProduction(purge As %Boolean = 0) As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
         #; create new production
        Set class = ##class(%Dictionary.ClassDefinition).%New(..#PRODUCTION)
        Set class.ProcedureBlock = 1
        Set class.Super = "Ens.Production"
        Set class.GeneratedBy = $ClassName()
        Set xdata = ##class(%Dictionary.XDataDefinition).%New()
        Set xdata.Name = "ProductionDefinition"
        Do xdata.Data.Write("<Production Name="""_..#PRODUCTION_""" LogGeneralTraceEvents=""true""></Production>")  
        Do class.XDatas.Insert(xdata)
        Set sc = $$$ADDSC(sc,class.%Save())
        Set sc = $$$ADDSC(sc,$System.OBJ.Compile(..#PRODUCTION,"fck-dv"))
        Set production = ##class(Ens.Config.Production).%OpenId(..#PRODUCTION)
        Set item = ##class(Ens.Config.Item).%New()
        Set item.ClassName = "diashenrique.messageviewer.Service.REST"
        Do production.Items.Insert(item)
        Set sc = $$$ADDSC(sc,production.%Save())
        Set item = ##class(Ens.Config.Item).%New()
        Set item.ClassName = "diashenrique.messageviewer.Operation.Consumer"
        Do production.Items.Insert(item)
        Set sc = $$$ADDSC(sc,production.%Save())    
        Set item = ##class(Ens.Config.Item).%New()
        Set item.ClassName = "diashenrique.messageviewer.Service.SendMessage"
        Do production.Items.Insert(item)
        Set sc = $$$ADDSC(sc,production.%Save())    
        Set item = ##class(Ens.Config.Item).%New()
        Set item.ClassName = "diashenrique.messageviewer.Operation.ConsumeMessageClass"
        Do production.Items.Insert(item)
        Set sc = $$$ADDSC(sc,production.%Save())    
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}

プロダクションクラスをビジネスオペレーションとサービスクラスに関連付けるために、クラスEns.Config.Itemを使用します。 これは、クラスの作成に%Dictionaryパッケージを使用したのか、VS Code、Studio、またはAtelierを使用したかに関係なく使用できます。

いずれにしても、達成できました! コードを使用して相互運用性プロダクションを作成できました。

ただし、このコードの元の目的を忘れてはいけません。拡張メッセージビューワの機能を示すプロダクションとメッセージを作成するという目的です。 以降のクラスメソッドを使用して、両方のビジネスサービスを実行し、メッセージを生成します。 

%Net.HttpRequestを使用たメッセージの生成:

ClassMethod GenerateMessages() As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
        Set action(0) = "/demoiris/send/message"
        Set action(1) = "/demoiris/send/something"
        For i=1:1:..#LIMIT {
            Set content = { }
            Set content.Message = "Hi, I'm just a random message named "_$Random(30000)
            Set content.Something = "Hi, I'm just a random something named "_$Random(30000)
            Set httprequest = ##class(%Net.HttpRequest).%New()
            Set httprequest.SSLCheckServerIdentity = 0
            Set httprequest.SSLConfiguration = ""
            Set httprequest.Https = 0
            Set httprequest.Server = "localhost"
            Set httprequest.Port = 9980
            Set serverUrl = action($Random(2))
            Do httprequest.EntityBody.Write(content.%ToJSON())
            Set sc = httprequest.Post(serverUrl) 
            Quit:$$$ISERR(sc)
        }
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}

EnsDirectorを使用したメッセージの生成:

ClassMethod GenerateUsingEnsDirector() As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
        For i=1:1:..#LIMIT {
            Set tSC = ##class(Ens.Director).CreateBusinessService("diashenrique.messageviewer.Service.SendMessage",.tService)
            Set message = "Message Generated By CreateBusinessService "_$Random(1000)
            Set tSC = tService.ProcessInput(message,.output)
            Quit:$$$ISERR(sc)
        }
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}
 
}

コードは以上です。 完全なプロジェクトは、https://github.com/diashenrique/iris-message-viewerをご覧ください。

プロジェクトの実行

では、プロジェクトの実際の動作を確認しましょう。 まず、git cloneまたはgit pullで、任意のローカルディレクトリにリポジトリを作成します。

git clone https://github.com/diashenrique/iris-message-viewer.git

次に、このディレクトリでターミナルを開き、次を実行します。

docker-compose build

最後に、プロジェクトでIRISコンテナを実行します。

docker-compose up -d

さらに、http://localhost:52773/csp/sys/UtilHome.cspを使用して管理ポータルにアクセスします。 次の画像のように、相互運用性のネームスペースMSGVIEWERが表示されます。

そしてこれが、私たちの愛らしいプロダクションです。2つのビジネスサービスと2つのビジネスオペレーションがあります。

非常にたくさんのメッセージがあります。

カスタムメッセージビューワですべてが稼働しているので、その機能を見てみましょう。

拡張メッセージビューワ

相互運用性プロダクションに有効になっているネームスペースのみが表示されることに注意してください。

http://localhost:52773/csp/msgviewer/messageviewer.csp

Interoperability Message Viewer
 

拡張メッセージビューワには、さまざまなフィルタの作成、nレベルへの列のグループ化、Excelへのエクスポートなどを行える機能と柔軟性が備わっています。
Interoperability Message Viewer
さまざまなフィルタを使用して、必要な結果を得ることができます。 また、Shiftキーを押しながら列のヘッダーをクリックすると、複数の並べ替えを使用することも可能です。 データグリッドをExcelにエクスポートすることもできるのです!

さらに、フィルタビルダーオプションを使用して、複雑なフィルタを作成することができます。

使用できる任意の列に対してデータをグループ化し、必要なnレベルを使用して情報をまとめることができます。 デフォルトでは、このグループはDate Created(作成日)フィールドを使用して作成されます。
データのグループ化

また、列を選択できる機能があります。 次のページには、Ens.MessageHeaderのすべての列があります。デフォルトの列のみが初期ビューに表示されていますが、 「Column Chooser」(列選択)ボタンを使って、ほかの列を選択することができます。

列セレクター

すべてのグループはワンクリックで折りたたみと展開が可能です。

SessionId(セッションID)フィールドの情報には、ビジュアルトレース機能へのリンクがあります。

ビジュアルトレース

必要に応じて、メッセージを再送することができます。 必要なメッセージを選択し、Resend をクリックするだけで再送信は完了です。 この機能には、次のクラスメソッドが使用されています。

##class(Ens.MessageHeader).ResendDuplicatedMessage(id)

最後に、前述のように、データグリッドをExcelにエクスポートすることができます。

Excelの結果には、キャッシュサーバーページ(CSP)に定義されているものと同じフォーマット、コンテンツ、およびグループが表示されます。

追伸: この問題への取り組みで大いに助けてくれた@Renan.Lourencoに、特に深くお礼申し上げます。

0
0 276
記事 Toshihiko Minamoto · 7月 6, 2021 8m read

Webサービスを呼び出す際、ビジネスオペレーションには、規定時間内に応答が返されない場合の動作を制御する設定があります。(これは、例えば、SOAPでない単純なHTTP呼び出しにも関係しているので注意してください)

関連する3つの主な設定は次のとおりです。

  • 応答タイムアウト
  • リモートWebサーバーから応答を受信するためのタイムアウトを指定します。

  • 再試行間隔
  • Ensembleの外部の宛先との接続を試行するまで待機する秒数。

  • 失敗タイムアウト
  • Ensembleの外部の宛先との接続を試行し続ける合計秒数。 この秒数が経過すると、ビジネスオペレーションはメッセージのデータを破棄し、エラーコードを返します。 

    文章でまとめると、これらは次のように連携します。

    Webサーバーからの応答を「応答タイムアウト」秒待ちます。 その時間までに応答がない場合は、「再試行間隔」秒が経過した後、Webサーバーを再度呼び出します。 これを、最初の試行が開始されてから「失敗タイムアウト」秒が経過するまで試行し続けます。

    次の例で説明します。

    次の設定を想定します。

    文章にすると、

    応答タイムアウト - 応答を7秒間待機します

    再試行間隔 - 10秒ごとに再試行します

    失敗タイムアウト - 30秒が経過したら試行を「諦める」

    したがって、応答がちょうど8秒後に戻ってきた場合は、次のシナリオが発生します。

    1. 00:00に最初の呼び出しを実行します
    2. 00:07に応答が返されないため、「応答タイムアウト」エラーが発生したことを内部的に確認し(イベントログに「エラーイベント」を記録し)、再試行ポリシーと設定に従って再試行します。 「失敗タイムアウト」にはまだ到達していないため、「再試行が必要」のフラグが立てられます。
    3. [ 00:08に、Webサーバーは応答を返しますが、タイムアウトですでにエラーが発生しているため、この応答は受信されません ]
    4. 00:10に再試行間隔に到達し、「再試行が必要」フラグが立てられているので、Webサーバーを再度呼び出します。
    5. 00:17に、応答がなく「応答タイムアウト」に再び到達します(前述したとおり、00:08/3番目のステップで返された応答が「無視/破棄」されてるので注意してください)。したがって、これも内部的にエラーとして示し(しかし、今回は別のイベントログエラーエントリは追加されません。イベントログエラーエントリは、最初の試行でのみ作成され、すべての再試行失敗で作成されるわけではありません。)「失敗タイムアウト」にまだ達していないため、再度「再試行が必要」フラグが立てられます。
    6. [ 00:18に、Webサーバーは応答を返しますが、これも受信されません ]
    7. 00:20に別の再試行間隔が経過して、3番目の再試行が行われます。
    8. 00:27に応答がなく、再び「応答タイムアウト」エラーが発生し、(失敗タイムアウト」にはまだ達していないため)再試行します。
    9. [ 00:28に、受信されない応答がサーバーから送信されます ]
    10. 00:30にまた再試行間隔に到達し、4番目(最後)の試行が行われます。
    11. 00:37に「応答タイムアウト」が再び発生します。今回は「失敗タイムアウト」を超過しているめ、「再試行が必要」フラグを立てずに諦めます。失敗タイムアウトを超過したというエラーイベントをイベントログに記録し、ビジネスオペレーションから呼び出し元のアイテムにエラーを返します。

    以下は、上記のシナリオ通りのサンプル呼び出しからの「証拠」の一部です。

    まず、サーバー側(SOAPログから)– 10秒間隔で4つの呼び出し/リクエストを受信し、そのたびにリクエストから8秒後に応答を返しました。


    05/31/2016 14:18:45 *********************
    Input to Web service with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    <SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
    ...
    </SOAP-ENV:Envelope>
    05/31/2016 14:18:53 *********************
    Output from Web service with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
    05/31/2016 14:18:55 *********************
    Input to Web service with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
    05/31/2016 14:19:03 *********************
    Output from Web service with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
    05/31/2016 14:19:05 *********************
    Input to Web service with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
    05/31/2016 14:19:13 *********************
    Output from Web service with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
    05/31/2016 14:19:15 *********************
    Input to Web service with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
    05/31/2016 14:19:23 *********************
    Output from Web service with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>

     

    次は、Ensemble BO/クライアント側から、10秒間隔で4回の試行があり、そのたびに7秒後に応答タイムアウトエラーがログに記録されたことが確認できます。

    クライアント側

    05/31/2016 14:18:45 *********************
    Output from Web client with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
     
    05/31/2016 14:18:52 *********************
    Input to Web client with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ERROR #5922: Timed out waiting for response
    string**** SOAP client return error. method=GetResponse, action=http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
         ERROR #5922: Timed out waiting for response
     
    05/31/2016 14:18:55 *********************
    Output from Web client with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
     
    05/31/2016 14:19:02 *********************
    Input to Web client with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ERROR #5922: Timed out waiting for response
    string**** SOAP client return error. method=GetResponse, action=http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
         ERROR #5922: Timed out waiting for response
     
    05/31/2016 14:19:05 *********************
    Output from Web client with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
     
    05/31/2016 14:19:12 *********************
    Input to Web client with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ERROR #5922: Timed out waiting for response
    string**** SOAP client return error. method=GetResponse, action=http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
         ERROR #5922: Timed out waiting for response
     
    05/31/2016 14:19:15 *********************
    Output from Web client with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ...
    </SOAP-ENV:Envelope>
     
    05/31/2016 14:19:22 *********************
    Input to Web client with SOAP action = http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
    ERROR #5922: Timed out waiting for response
    string**** SOAP client return error. method=GetResponse, action=http://tempuri.org/Test.WSTimeouts.WebService.GetResponse
         ERROR #5922: Timed out waiting for response

    Ensembleの視覚的なトレースは次のとおりです。

    そして、これがイベントログエントリです。

    トレースイベントをオンにしたサンプルイベントログ(画像内のテキストを読みやすくするためにズームインする必要がある場合があります)

    ここには、上記のシナリオの「内部動作」の一部が表示されています。

    ログIDが684番のところでは17:09:16に最初の呼び出しが行われます。

    次に、7秒後(09:23)に応答タイムアウトエラー(685番)が発生します。 次に、オペレーションは、エラーをログに記録し(687番)、再試行間隔までさらに3秒間待機することを決定します。10秒の再試行間隔から7秒の応答タイムアウトを引いたもの(688番 - 690番)です。

    3秒の待機時間が経過した後(09:26、691番)、2回目の試行が行われます(692番)。これらの試行の結果と後続の動作は4回目の試行(704番)まで同じままです。 4回目の試行が失敗した(09:53、705番)後、失敗タイムアウト(30秒)を超過したため、もう1つの試行は行われません。

    0
    0 874
    記事 Mihoko Iijima · 10月 27, 2020 12m read

    この記事はこちらの投稿の続きの内容です。

    前回の記事では、コンポーネント間のデータ送受信に使用される メッセージ について、作成するときの考え方や定義方法を確認しました。

    今回の記事では、コンポーネントの作成方法の中から、ビジネス・オペレーションの作成について解説します。

    早速サンプルを参照しながらコードを確認します。

    0
    0 993
    記事 Minoru Horita · 7月 24, 2020 1m read

    この連載記事では、InterSystemsデータプラットフォーム用のPython Gatewayについて説明します。 また、InterSystems IRISからPythonコードなどを実行します。 このプロジェクトは、InterSystems IRIS環境にPythonの力を与えます。

    • 任意のPythonコードを実行する
    • InterSystems IRISからPythonへのシームレスなデータ転送
    • Python相互運用アダプタでインテリジェントな相互運用ビジネスプロセスを構築する
    • InterSystems IRISからのPythonコンテキストの保存、調査、変更、復元

    その他の記事

    現時点での連載計画です(変更される可能性があります)。

    はじめに

    前回はターミナルからPython Gatewayを試しましたが、今回は相互運用性プロダクションを介してPythonゲートウェイを使ってみましょう。 この記事では、Pythonの重要な相互運用性インターフェースである isc.py.ens.Operation について説明します。 このインターフェースにより、次のことが可能になります。

    • Pythonコードを実行してリクエストされた変数を返す(文字列/ストリーム)
    • コンテキストを保存/復元する
    • Pythonにデータを読み込む

    一般的に言えば、これは isc.py.Main の相互運用ラッパーです。 相互運用アダプタである isc.py.ens.Operationは、相互運用性プロダクションからPythonプロセスと対話する機能を提供します。 現在、5つのリクエストがサポートされています。

    • isc.py.msg.ExecutionRequest を介してPythonコードを実行します。 リクエストされた変数値を含む isc.py.msg.ExecutionResponse を返します。
    • isc.py.msg.StreamExecutionRequest を介してPythonコードを実行します。 リクエストされた変数値を含む isc.py.msg.StreamExecutionResponse を返します。 上記と同じですが、文字列ではなくストリームを受け付けて返します。
    • isc.py.msg.QueryRequest を使用してSQLクエリからデータセットを設定します。 Ens.Response を返します。
    • isc.py.msg.GlobalRequest/isc.py.msg.ClassRequest/isc.py.msg.TableRequest を使用してグローバル/クラス/テーブルからより高速にデータセットを設定します。 Ens.Response を返します。
    • isc.py.msg.SaveRequest を介してPythonコンテキストを保存します。 コンテキストIDを含む Ens.StringResponse を返します。
    • isc.py.msg.RestoreRequest 経由でPythonコンテキストを復元します。

    ただし、isc.py.ens.Operation には次の2つの設定があります。

    • Initializer - isc.py.init.Abstract を実装するクラスを選択します。 関数、モジュール、クラスなどを読み込むために使用できます。 プロセスの開始時に実行されます。
    • PythonLib - (Linuxのみ)読み込みエラーが表示される場合、これを libpython3.6m.so か共有ライブラリのフルパスに設定します。

    ビジネスプロセスの記述

    次のような、ビジネスプロセスの開発を容易にする2つのユーティリティクラスがあります。

    • isc.py.ens.ProcessUtilsを使用すると、変数を置換してアノテーションを取得できます。
    • isc.py.util.BPEmulator を使用すると、Pythonの相互運用ビジネスプロセスを簡単にテストできます。 現在のジョブで、ビジネスプロセス(Python部分)を実行できます。

    変数の置換

    isc.py.ens.ProcessUtils を継承するすべてのビジネスプロセスは、GetAnnotation(name) メソッドを使用し、アクティビティ名を指定してアクティビティのアノテーションを取得できます。 アクティビティのアノテーションには、Pythonに渡される前にObjectScript側で計算される変数を含めることができます。 以下は、変数置換の構文です。

    • ${class:method:arg1:...:argN} - メソッドを実行します
    • #{expr} - ObjectScriptコードを実行します

    例えば、Correlation Matrix: Graph アクティビティ: f.savefig(r'#{process.WorkDirectory}SHOWCASE${%PopulateUtils:Integer:1:100}.png') でテスト isc.py.test.Process ビジネスプロセスをチェックします。

    この例の場合:

    • #{process.WorkDirectory} は、isc.py.test.Process クラスと現在のビジネスプロセスのインスタンスである process オブジェクトの WorkDirectory プロパティを返します。
    • ${%PopulateUtils:Integer:1:100}1100 の引数を渡す %PopulateUtils クラスの Integer メソッドを呼び出し、 1...100 の範囲でランダムな整数を返します。

    ビジネスプロセスのテスト

    テスト相互運用性プロダクションとテストビジネスプロセスは、デフォルトでPythonゲートウェイの一部として使用できます。 これらは以下の手順で使用できます。

    1. OSのbashシェルで、pip install pandas matplotlib seaborn を実行します。
    2. do ##class(isc.py.test.CannibalizationData).Import() を実行してテストデータを生成します。
    3. isc.py.test.Production プロダクションを起動します。
    4. 空の Ens.Request メッセージを isc.py.test.Process に送信します。

    これらがどのように連携するか見てみましょう。 isc.py.test.Process をBPLエディタ(またはStudio)で開いてください。

    コード実行の呼び出し

    以下は、Python コードを実行するのに最も重要な呼び出しです。

    リクエストは isc.py.msg.ExecutionRequest であり、プロパティは次のとおりです。

    • Code - 実行するPythonコードです。
    • SeparateLines - 受信メッセージを実行用に複数の行に分割します。 $c(10) (\n) が行の分割に使用されます。 メッセージ全体を一度に処理することはお勧めしません。この機能は、def や同様の複数行式の処理にのみ使用できます。 デフォルト値は0です。
    • Variables - 応答メッセージで取得する変数をカンマで区切ったリストです。
    • Serialization - 返したい変数のシリアライズ方法です。Str / Repr / JSON / Pickle / Dill のオプションがあり、デフォルト値は Str です。

    この例では Code プロパティのみを設定していますので、残りのプロパティはすべてデフォルト値になっています。 私たちはこれを、実行時に変数置換を実行した後にアノテーションを返す process.GetAnnotation("Import pandas") を呼び出して設定しました。 最終的には、import pandas as pd 文字列がPythonに渡されます。 GetAnnotation は複数行のPythonスクリプトをセットアップするのに役立ちますが、制限はありません。 Code プロパティは好きなように設定できます。

    変数取得の呼び出し

    他にも isc.py.msg.ExecutionRequest を使用する Correlation Matrix: Tabular という興味深い呼び出しがあります。

    これはPython側でCorrelation Matrixを計算して corrmat を取得し、次のようにリクエストにプロパティを設定してInterSystems IRISにJSON形式で返します。

    • Variables: "corrmat"
    • Serialization: "JSON"

    結果は次のように視覚的なトレースで確認できます。

    また、これが今後ビジネスプロセスで必要な場合は、callresponse.Variables.GetAt("corrmat") を使って保存できます。

    データ転送の呼び出し

    次に、InterSystems IRISからPythonへのデータ転送について説明します。すべてのデータ転送リクエストは、以下の共通プロパティを提供する isc.py.msg.DataRequest を拡張します。

    • Variable - 設定するPython変数です。
    • Type - 変数の型。現在は、dataframe(pandasのデータフレーム)と list がサポートされています。
    • Namespace - データを取得するネームスペースです。 'isc.py' パッケージをこのネームスペースで使用できる必要があります。

    その上に以下の4つの具象クラスがあります。

    • isc.py.msg.QueryRequest - SQL結果セットを転送するために Query プロパティを設定します。
    • isc.py.msg.ClassRequest - クラスデータを転送するために Class プロパティを設定します。
    • isc.py.msg.TableRequest - テーブル全体を転送するために Table プロパティを設定します。
    • isc.py.msg.GlobalRequest - グローバルを転送するために Global プロパティを設定します。

    このテストプロセスでは、RAW 呼び出しをチェックして isc.py.msg.QueryRequest の動作を確認します。

    Pythonコンテキスト呼び出しの保存/復元

    最後に、PythonコンテキストをInterSystems IRISに永続化します。そのためには、次を指定して isc.py.msg.SaveRequest を送信してください。

    • Mask - Mask を満たす変数のみが保存されます。 ワイルドカード * および ? を使用できます (例:"Data*,Figure?")。 デフォルト値は * です。
    • MaxLength - 保存される変数の最大長です。 変数をシリアライズした結果がこの値よりも長い場合、結果は無視されます。 すべてを取得するには、0に設定してください。 デフォルト値は $$$MaxStringLength です。
    • Name - コンテキスト名です(任意)。
    • Description - 拡張コンテキスト情報です(任意)。

    例えば、テストプロセスでは Save Context の呼び出しをチェックします。 保存されたコンテキストの Id を含む Ens.StringResponse を返します。

    対応する isc.py.msg.RestoreRequest はInterSystems IRISからPythonにコンテキストを読み込みます。

    • ContextId - 復元するコンテキストの識別子。
    • Clear - 復元前にコンテキストをクリアします。

    要約

    Python Gatewayを使用すると、InterSytems IRISとPythonをシームレスに統合できます。 これを使用し、Pythonの機能を相互運用性プロダクションに追加してください。

    リンク

    イラスト付きガイド

    ML Toolkitユーザーグループには、イラスト付きのガイドもあります。 ML Toolkitユーザーグループは、InterSystems社のGitHub組織の一部として設定されている非公開GitHubリポジトリです。 このリポジトリは、Python Gatewayを含むML Toolkitコンポーネントをインストール、学習、またはすでに使用している外部ユーザーを対象としています。 ML Toolkitユーザーグループに参加するには、以下の内容を含む簡単なメールを MLToolkit@intersystems.com 宛に送信してください(グループメンバーが議論中にあなたを認識して特定するために必要です)。

    • GitHubのユーザー名
    • 氏名(英文字表記の名前、姓の順)
    • 組織(勤務先、通学先、または在宅勤務)
    • 役職(組織での実際の役職、「学生」、または「無所属」)
    • 国(本拠地としている国)
    0
    0 200