web-dev-qa-db-ja.com

Pythonコードを主にScalaアプリケーションに統合するためのアプローチは、成功したのでもう一度使用しましたか?

私は主にScalaアプリケーションを持っています。私はPythonコードをこのアプリケーションに統合する方法に興味があります。それは、あなたが個人的に成功することを証明する方法です。

この文脈で

  • 統合とは、Scalaコードからの呼び出しPythonコードを許可し、結果を使用するか、例外にアクセスすることを意味します
  • 成功とは、2つの言語が連携してビジネス価値を提供し、同じチームがこのアプローチを2回使用したため、このアプローチが複数回使用されたことを意味します。

うまくいけば、私は事実の観察を求めているので、この質問は議論ではなく事実の答えを認めます。ただし、これが主観的すぎる場合は、閉じるときに次のいずれかを提案してください。

  • この質問を主観的ではない方法で質問する方法または
  • この種の質問をすることができるサイトに私を向けてください。

ありがとう。

5
Janek Bogucki

次のように、変数を介して結果をキャプチャし、STDERRを介して例外をキャプチャします。

scalaの場合:

import sys.process._
def callPython(): Unit = {
    val result = "python /fullpath/mypythonprogram.py" ! ProcessLogger(stdout append _, stderr append _)
    println(result)
    println("stdout: " + stdout)
    println("stderr: " + stderr)
}

そしてPythonでは:

try:
    throws()
    return 0
except Exception as err:
    sys.stderr.write(f'Exception: {err}')
    return 1

詳細については、パッケージprocesshere を参照してください。 ProcessBuilderここ およびProcessLogger-もご覧ください- ここ

4
tale852150

それぞれのケースが異なり、すべてのアプローチが異なるチームによってうまく使用されているため、これに対する単一の答えはありません。

一般に、3つのアプローチがあります。

  1. 両方の言語のランタイムが同じ場合は、両方の言語をそのランタイムにコンパイルして、外部関数インターフェイスを使用できます。このシナリオでは、JythonとScalaを使用します。どちらもJVM上で実行されます。これは通常、最も速く、オーバーヘッドが最も少ないですが、各言語がオブジェクトをその言語で処理する方法でインピーダンスに対処する必要があります。また、分離がないため、どちらかの言語で不十分に記述されたコードが他をクラッシュさせる可能性があります。さらに、これを複数のマシンに拡張するのは面倒な場合があります。
  2. メインアプリで各リクエストを処理するときにサブプロセスを生成できます。メインプロセスは、stdinとstdoutを使用してデータをストリーミングすることでサブプロセスと通信し、場合によっては他のパイプまたは他のOS固有のIPCを使用します。サブプロセスがパイプラインで使用できるプログラムの filter タイプの場合、これが一般的に最適です。メインリクエストごとにサブプロセスを作成するとオーバーヘッドが発生しますが、LinuxなどのUnixベースのシステムでこれを行っている場合、システムが最適化されているため、新しいプロセスの作成は非常に高速です。
  3. プロセス間通信を作成し、メッセージパッシングAPIを使用してマイクロサービスと通信できます。この例は、HTTPアプリケーションサーバーを実行するか、ドメインソケットと通信するマイクロサービスを実行することです。このアプローチでは、メッセージのレンダリング、コピー、解析によるオーバーヘッドが発生するため、小さな呼び出しを多数行うよりも、メッセージが粗い場合に最適です。明示的なAPIを設計する必要がありますが、このアプローチは通常、長期的にはより単純であり、クラッシュは別個であり、他のプロセスに影響を与えないため、より堅牢にすることができます。異なるマシンでプロセスを実行する必要がある場合に、明示的なAPIを使用すると、このアプローチがより簡単になるので、このアプローチははるかに簡単にスケーリングできます。
3
Lie Ryan