Konkurensi dan ketahanan gaya langsung yang aman untuk Scala pada JVM. Membutuhkan JDK 21 & Scala 3. Area yang ingin kami tutupi dengan sapi adalah:
Semua hal di atas harus memungkinkan observabilitas logika bisnis yang diatur. Kami bertujuan untuk memungkinkan menulis kode sederhana, berorientasi ekspresi dalam gaya fungsional. Kami ingin menjaga overhead sintaks seminimal mungkin, melestarikan jejak tumpukan yang ramah pengembang, dan tanpa berkompromi.
Beberapa hal di atas sudah dibahas dalam API, beberapa muncul di masa depan. Kami akan menyukai bantuan Anda dalam membentuk proyek!
Untuk menguji sapi, gunakan ketergantungan berikut, menggunakan kedua SBT:
" com.softwaremill.ox " %% " core " % " 0.5.3 "
Atau Scala-cli:
//> using dep " com.softwaremill.ox::core:0.5.3 "
Dokumentasi tersedia di https://ox.softwaremill.com, Scaladocs dapat dijelajahi di https://javadoc.io.
Jalankan dua perhitungan secara paralel:
def computation1 : Int = { sleep( 2 .seconds); 1 }
def computation2 : String = { sleep( 1 .second); " 2 " }
val result1 : ( Int , String ) = par(computation1, computation2)
// (1, "2")
Batas waktu perhitungan:
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
Balapan dua perhitungan:
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
Konkurensi Struktur & Pengawasan:
// equivalent of par
supervised {
val f1 = fork { sleep( 2 .seconds); 1 }
val f2 = fork { sleep( 1 .second); 2 }
(f1.join(), f2.join())
}
Penanganan kesalahan dalam lingkup konkurensi terstruktur:
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")
Coba lagi perhitungan:
def computationR : Int = ???
retry( RetryConfig .backoff( 3 , 100 .millis, 5 .minutes, Jitter . Equal ))(computationR)
Ulangi perhitungan:
def computationR : Int = ???
repeat( RepeatConfig .fixedRateForever( 100 .millis))(computationR)
Alokasikan sumber daya dalam lingkup:
supervised {
val writer = useCloseableInScope( new java.io. PrintWriter ( " test.txt " ))
// ... use writer ...
} // writer is closed when the scope ends (successfully or with an error)
Buat aplikasi yang dimatikan dengan bersih saat terganggu dengan 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
Aktor-aktor jenis-aman sederhana:
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 ))
Buat Aliran Sederhana & Transformasi Menggunakan API Fungsional:
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))
Buat aliran yang melakukan I/O dan kelola konkurensi:
def sendHttpRequest ( entry : String ) : Unit = ???
Flow
.fromInputStream( this .getClass().getResourceAsStream( " /list.txt " ))
.linesUtf8
.mapPar( 4 )(sendHttpRequest)
.runDrain()
Gabungkan dua aliran, dengan benar menangani kegagalan kedua cabang:
val f1 = Flow .tick( 123 .millis, " left " )
val f2 = Flow .tick( 312 .millis, " right " )
f1.merge(f2).take( 100 ).runForeach(println)
Integrasi aliran dengan komponen lain menggunakan API imperatif:
def readNextBatch () : List [ String ] = ???
Flow .usingEmit { emit =>
forever :
readNextBatch().foreach(emit.apply)
}
Gunakan saluran kinerja tinggi yang dapat diselesaikan untuk komunikasi antar-alat berat dalam lingkup konkurensi:
val c = Channel .buffered[ String ]( 8 )
c.send( " Hello, " )
c.send( " World " )
c.done()
Pilih dari saluran seperti Go:
val c = Channel .rendezvous[ Int ]
val d = Channel .rendezvous[ Int ]
select(c.sendClause( 10 ), d.receiveClause)
Buka eithers dan gabungkan kesalahan dalam jenis serikat:
val v1 : Either [ Int , String ] = ???
val v2 : Either [ Long , String ] = ???
val result : Either [ Int | Long , String ] = either :
v1.ok() ++ v2.ok()
Nilai pipa & ketuk untuk fungsi untuk menggunakan dot-syntax:
def compute : Int = ???
def computeMore ( v : Int ) : Long = ???
compute
.pipe( 2 * _)
.tap(println)
.pipe(computeMore)
Lebih banyak di dokumen!.
Tujuan yang lebih luas dari Scala bergaya langsung adalah memungkinkan tim untuk memberikan perangkat lunak yang berfungsi dengan cepat dan dengan percaya diri. Proyek kami yang lain, termasuk Klien STTP dan Tapir, juga termasuk integrasi yang langsung dirancang untuk gaya langsung.
Selain itu, juga periksa Proyek Gears, perpustakaan multi-platform eksperimental juga mencakup Scala bergaya langsung.
Semua saran selamat datang :)
Untuk mengkompilasi dan menguji, jalankan:
sbt compile
sbt test
Lihat daftar masalah dan pilih satu! Atau laporkan milik Anda sendiri.
Jika Anda memiliki keraguan tentang mengapa atau bagaimana sesuatu bekerja, jangan ragu untuk mengajukan pertanyaan tentang wacana atau melalui GitHub. Ini mungkin berarti bahwa dokumentasi, skala atau kode tidak jelas dan dapat ditingkatkan untuk kepentingan semua.
Untuk mengembangkan dokumentasi, Anda dapat menggunakan skrip doc/watch.sh
, yang menjalankan Sphinx menggunakan Python. Gunakan doc/requirements.txt
untuk mengatur lingkungan Python Anda dengan pip
. Atau, jika Anda seorang pengguna nix, jalankan nix develop
di doc/
untuk memulai shell dengan lingkungan yang memungkinkan untuk menjalankan watch.sh
. Selain itu, Anda dapat menggunakan tugas SBT compileDocumentation
untuk memverifikasi, bahwa semua cuplikan kode dikompilasi dengan benar.
Ketika Anda sudah siap, lihat panduan "Cara Mempersiapkan PR" kami. Terima kasih! :)
Kami menawarkan layanan pengembangan komersial. Hubungi kami untuk mempelajari lebih lanjut tentang kami!
Hak Cipta (C) 2023-2024 Softwaremill https://softwaremill.com.