Безопасное параллелизм прямого стиля и устойчивость для Scala на JVM. Требуется 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.
Запустите два вычисления параллельно:
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
Гонка Два вычисления:
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))
Создайте потоки, которые выполняют ввод -вывод и управляют параллелизмом:
def sendHttpRequest ( entry : String ) : Unit = ???
Flow
.fromInputStream( this .getClass().getResourceAsStream( " /list.txt " ))
.linesUtf8
.mapPar( 4 )(sendHttpRequest)
.runDrain()
Объедините два потока, правильно обрабатывая сбой любого ветви:
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()
Значения трубы и нажатия для функций для использования точечного синтаксиса:
def compute : Int = ???
def computeMore ( v : Int ) : Long = ???
compute
.pipe( 2 * _)
.tap(println)
.pipe(computeMore)
Больше в документах!.
Более широкая цель Scala прямого стиля-это позволяет командам быстро и с уверенностью доставлять рабочее программное обеспечение. Наши другие проекты, в том числе клиент и тапир STTP, также включают интеграции, непосредственно адаптированные к прямому стилю.
Кроме того, также ознакомьтесь с проектом Gears, экспериментальной многоплатформенной библиотекой, также охватывающей Scala прямого стиля.
Все предложения приветствуются :)
Для компиляции и тестирования, запустите:
sbt compile
sbt test
Смотрите список проблем и выберите один! Или сообщить о своем.
Если у вас есть сомнения в том, почему или как что -то работает, не стесняйтесь задать вопрос о дискурсе или через GitHub. Это, вероятно, означает, что документация, Scaladocs или код неясны и могут быть улучшены в интересах всех.
Чтобы разработать документацию, вы можете использовать сценарий doc/watch.sh
, который запускает Sphinx с помощью Python. Используйте doc/requirements.txt
для настройки вашей среды Python с помощью pip
. В качестве альтернативы, если вы пользователь NIX, запустите nix develop
в doc/
чтобы запустить оболочку с средой, позволяющей запускать watch.sh
. Более того, вы можете использовать задачу SBT compileDocumentation
для проверки, чтобы все фрагменты кода правильно компилировались.
Когда у вас есть PR, посмотрите на наше руководство «Как приготовить хороший пиар». Спасибо! :)
Мы предлагаем услуги коммерческого развития. Свяжитесь с нами, чтобы узнать о нас больше!
Copyright (C) 2023-2024 Softwaremill https://softwaremill.com.