JVM上のScalaの安全なダイレクトスタイルの並行性と回復力。 JDK 21とSCALA 3が必要です。牛で覆いたい領域は次のとおりです。
上記のすべてが、組織化されたビジネスロジックの観察可能性を可能にする必要があります。単純な表現指向のコードを機能スタイルで作成できるようにすることを目指しています。構文のオーバーヘッドを最小限に抑え、パフォーマンスを損なうことなく、開発者に優しいスタックトレースを保存したいと考えています。
上記のいくつかはすでにAPIで対処されており、一部は将来的に登場しています。プロジェクトの形成にご協力ください!
牛をテストするには、SBTを使用して、次の依存関係を使用します。
" com.softwaremill.ox " %% " core " % " 0.5.3 "
またはscala-cli:
//> using dep " com.softwaremill.ox::core:0.5.3 "
ドキュメントはhttps://ox.softwaremill.comで入手できます。Scaladocsはhttps://javadoc.ioで閲覧できます。
2つの計算を並行して実行します。
def computation1 : Int = { sleep( 2 .seconds); 1 }
def computation2 : String = { sleep( 1 .second); " 2 " }
val result1 : ( Int , String ) = par(computation1, computation2)
// (1, "2")
計算のタイムアウト:
def computation3 : Int = { sleep( 2 .seconds); 1 }
val result2 : Either [ Throwable , Int ] = either.catching(timeout( 1 .second)(computation3))
// `timeout` only completes once the loosing branch is interrupted & done
レース2つの計算:
def computation4 : Int = { sleep( 2 .seconds); 1 }
def computation5 : Int = { sleep( 1 .second); 2 }
val result3 : Int = raceSuccess(computation4, computation5)
// as before, the loosing branch is interrupted & awaited before returning a result
構造化された並行性と監督:
// equivalent of par
supervised {
val f1 = fork { sleep( 2 .seconds); 1 }
val f2 = fork { sleep( 1 .second); 2 }
(f1.join(), f2.join())
}
構造化された並行性範囲内でのエラー処理:
supervised {
forkUser :
sleep( 1 .second)
println( " Hello! " )
forkUser :
sleep( 500 .millis)
throw new RuntimeException ( " boom! " )
}
// on exception, all other forks are interrupted ("let it crash")
// the scope ends & re-throws only when all forks complete (no "leftovers")
計算を再試行します:
def computationR : Int = ???
retry( RetryConfig .backoff( 3 , 100 .millis, 5 .minutes, Jitter . Equal ))(computationR)
計算を繰り返します:
def computationR : Int = ???
repeat( RepeatConfig .fixedRateForever( 100 .millis))(computationR)
範囲内のリソースを割り当てる:
supervised {
val writer = useCloseableInScope( new java.io. PrintWriter ( " test.txt " ))
// ... use writer ...
} // writer is closed when the scope ends (successfully or with an error)
Sigint/Sigtermで中断されたときにきれいにシャットダウンするアプリを作成します。
object MyApp extends OxApp :
def run ( args : Vector [ String ])( using Ox ) : ExitCode =
// ... your app's code ...
// might use fork {} to create top-level background threads
ExitCode . Success
シンプルなタイプセーフ俳優:
class Stateful { def increment ( delta : Int ) : Int = ??? }
supervised :
val ref = Actor .create( new Stateful )
// ref can be shared across forks, but only within the concurrency scope
ref.ask(_.increment( 5 ))
機能的なAPIを使用して、単純なフローと変換を作成します。
Flow .iterate( 0 )(_ + 1 ) // natural numbers
.filter(_ % 2 == 0 )
.map(_ + 1 )
.intersperse( 5 )
// compute the running total
.mapStateful(() => 0 ) { (state, value) =>
val newState = state + value
(newState, newState)
}
.take( 10 )
.runForeach(n => println(n.toString))
I/Oを実行するフローを作成し、並行性を管理します。
def sendHttpRequest ( entry : String ) : Unit = ???
Flow
.fromInputStream( this .getClass().getResourceAsStream( " /list.txt " ))
.linesUtf8
.mapPar( 4 )(sendHttpRequest)
.runDrain()
2つのフローをマージし、いずれかのブランチの障害を適切に処理します。
val f1 = Flow .tick( 123 .millis, " left " )
val f2 = Flow .tick( 312 .millis, " right " )
f1.merge(f2).take( 100 ).runForeach(println)
命令的なAPIを使用して、フローを他のコンポーネントと統合します。
def readNextBatch () : List [ String ] = ???
Flow .usingEmit { emit =>
forever :
readNextBatch().foreach(emit.apply)
}
並行性スコープ内でフォーク間通信に完全な高性能チャネルを使用します。
val c = Channel .buffered[ String ]( 8 )
c.send( " Hello, " )
c.send( " World " )
c.done()
GOのようなチャネルから選択します。
val c = Channel .rendezvous[ Int ]
val d = Channel .rendezvous[ Int ]
select(c.sendClause( 10 ), d.receiveClause)
ユニオンタイプのエラーを解き、エラーを組み合わせます。
val v1 : Either [ Int , String ] = ???
val v2 : Either [ Long , String ] = ???
val result : Either [ Int | Long , String ] = either :
v1.ok() ++ v2.ok()
dot-syntaxを使用する関数への値とタップ値:
def compute : Int = ???
def computeMore ( v : Int ) : Long = ???
compute
.pipe( 2 * _)
.tap(println)
.pipe(computeMore)
ドキュメントの詳細!
ダイレクトスタイルのSCALAのより広い目標は、チームが迅速かつ自信を持って作業ソフトウェアを提供できるようにすることです。 STTPクライアントやTapirを含む他のプロジェクトには、直接的なスタイルに合わせて直接調整された統合も含まれています。
さらに、ダイレクトスタイルのSCALAもカバーする実験的なマルチプラットフォームライブラリであるGears Projectもチェックしてください。
すべての提案を歓迎します:)
コンパイルしてテストするには、実行します。
sbt compile
sbt test
問題のリストを参照して、それを選択してください!またはあなた自身を報告してください。
何かが何の仕組みに疑問を抱いている場合は、談話やgithub経由で質問することをheしないでください。これはおそらく、ドキュメント、スカラドック、またはコードが不明であり、すべての利益のために改善できることを意味します。
ドキュメントを開発するには、Pythonを使用してSphinxを実行するdoc/watch.sh
スクリプトを使用できます。 doc/requirements.txt
を使用して、Python環境をpip
でセットアップします。または、nixユーザーの場合は、 doc/
nix develop
して、 watch.sh
実行できる環境でシェルを起動します。さらに、 compileDocumentation
SBTタスクを使用して、すべてのコードスニペットが適切にコンパイルされることを確認できます。
PRの準備ができたら、「良いPRを準備する方法」ガイドをご覧ください。ありがとう! :)
商業開発サービスを提供しています。私たちの詳細については、お問い合わせください!
Copyright(c)2023-2024 Softwaremill https://softwaremill.com。