JVM의 Scala에 대한 안전한 직접 스타일 동시성 및 탄력성. JDK 21 및 Scala 3이 필요합니다. 우리가 황소로 덮고 싶은 영역은 다음과 같습니다.
위의 모든 것은 조율 된 비즈니스 논리의 관찰 가능성을 허용해야합니다. 우리는 기능적 스타일로 간단하고 표현식 지향 코드를 작성하는 것을 목표로합니다. 우리는 구문 오버 헤드를 최소로 유지하여 개발자 친화적 인 스택 트레이스를 보존하고 성능을 손상시키지 않기를 원합니다.
위의 일부는 이미 API에서 다루어졌으며 일부는 앞으로 나올 것입니다. 우리는 프로젝트를 형성하는 데 도움을주고 싶습니다!
OX를 테스트하려면 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))
I/O를 수행하고 동시성을 관리하는 흐름을 만듭니다.
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-Like 채널에서 선택하십시오.
val c = Channel .rendezvous[ Int ]
val d = Channel .rendezvous[ Int ]
select(c.sendClause( 10 ), d.receiveClause)
UNFAP EITHERS 및 UNION 유형의 오류를 결합합니다.
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)
문서에서 더 많이!.
직접 스타일의 스칼라의 더 넓은 목표는 팀이 작업 소프트웨어를 신속하고 자신있게 제공 할 수있게하는 것입니다. STTP 클라이언트와 Tapir를 포함한 다른 프로젝트에는 직접 스타일을 향한 직접 맞춤형 통합이 포함되어 있습니다.
또한 직접 스타일의 스칼라를 다루는 실험적인 멀티 플랫폼 라이브러리 인 기어 프로젝트를 확인하십시오.
모든 제안을 환영합니다 :)
컴파일하고 테스트하려면 실행 :
sbt compile
sbt test
문제 목록을보고 하나를 선택하십시오! 또는 자신을보고하십시오.
왜 또는 어떻게 작동하는지에 대해 의문의 여지가 있다면 주저하지 말고 담론이나 Github를 통해 질문을하십시오. 이것은 아마도 문서, Scaladocs 또는 Code가 불분명하고 모든 사람의 이익을 위해 개선 될 수 있음을 의미합니다.
문서를 개발하려면 Python을 사용하여 스핑크스를 실행하는 doc/watch.sh
스크립트를 사용할 수 있습니다. doc/requirements.txt
사용하여 pip
로 파이썬 환경을 설정하십시오. 또는 NIX 사용자 인 경우 doc/
에서 nix develop
실행하여 watch.sh
실행할 수있는 환경이있는 쉘을 시작하십시오. 또한 compileDocumentation
SBT 작업을 사용하여 모든 코드 스 니펫이 올바르게 컴파일되는지 확인할 수 있습니다.
PR 준비가되면 "좋은 PR 준비 방법"가이드를 살펴보십시오. 감사해요! :)
우리는 상업적 개발 서비스를 제공합니다. 우리에 대해 자세히 알아 보려면 저희에게 연락하십시오!
저작권 (C) 2023-2024 SoftWaremill https://softwaremill.com.