Skip to content
This repository has been archived by the owner on Jan 20, 2025. It is now read-only.

Commit

Permalink
Upgrade to Scala 3 (#534)
Browse files Browse the repository at this point in the history
* build.sbt and fmt migrated

* migrated zio-actors

* migrated zio-persistence

* migrated persistence-jdbc

* migrated akka-interop

* migrated-examples

* removed empty test file

* generated new docs

* remove most workflows

* Revert "remove most workflows"

This reverts commit 1f50136.

* Revert "generated new docs"

This reverts commit 94e26bb.

* reverted ! interface

* private val inte BuildHelper

* fix docs

* more docs warnings fixed

* Fixes from compiler-flags, unused private functions

* updated README

* type warnings fixed

* Fixed serialization....

* Separate classes

* scala-2 folder

* Add annotation for overridden Serialization method

* formatting

* Get all versions to play together

* formatting

* genereted docs/README

* Added Scala 3.3.1 as CI build

* Add docs again to build

* formatting in scala-3 folder

* fix packages

* simplify

* Break out as much common logic as possible

* only use refActorMap in ActorSystem, and change name to be consistent

* Helped scala 2.12 compiler

* formating

* BaseActorSystem private

* Fix docs not compiling

* Break out logic for Context class

* README finds version

* fix website-workflow import error

* sbt publishLocal fails. Reverted imports to ._

* removed unused file

* Removed more scala 3 syntax

* bit sloppy, reverted more imports and wildcards

* remove xSource3 flag for scala2.12

* Manges to move all business logic to BaseActorSystem

* reverted akka upgrade

---------

Co-authored-by: Ragnar Englund <[email protected]>
  • Loading branch information
Ragazoor and Ragge-dev authored Jan 15, 2024
1 parent f8782b4 commit bff7ccf
Show file tree
Hide file tree
Showing 35 changed files with 831 additions and 582 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
fail-fast: false
matrix:
java: ['[email protected]', '[email protected]']
scala: ['2.12.15', '2.13.8']
scala: ['2.12.15', '2.13.8', '3.3.1']
steps:
- uses: actions/[email protected]
- uses: olafurpg/setup-scala@v10
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,9 @@ captures/
.idea/codeStyles/Project.xml
.idea/hydra.xml

# VsCode
.vscode/*

# Keystore files
# Uncomment the following line if you do not want to check your keystore files in.
#*.jks
Expand Down Expand Up @@ -461,6 +464,7 @@ project/plugins/project/
.idea
project/secret
project/metals.sbt
project/project/*

# mdoc
website/node_modules
Expand Down
9 changes: 5 additions & 4 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
version = "2.6.3"
version = "3.7.15"
maxColumn = 120
align = most
align.preset = most
continuationIndent.defnSite = 2
docstrings.style = Asterisk
assumeStandardLibraryStripMargin = true
docstrings = JavaDoc
lineEndings = preserve
includeCurlyBraceInSelectChains = false
danglingParentheses = true
danglingParentheses.preset = true
spaces {
inImportCurlyBraces = true
}
optIn.annotationNewlines = true

rewrite.rules = [SortImports, RedundantBraces]
runner.dialect = scala3
75 changes: 75 additions & 0 deletions actors/src/main/scala-2/zio/actors/ActorSystem.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package zio.actors

import zio.actors.ActorSystemUtils._
import zio.actors.ActorsConfig._
import zio.{ Ref, Task, UIO, ZIO }

import java.io._

/**
* Object providing constructor for Actor System with optional remoting module.
*/
object ActorSystem {

/**
* Constructor for Actor System
*
* @param sysName
* \- Identifier for Actor System
* @param configFile
* \- Optional configuration for a remoting internal module. If not provided the actor system will only handle local
* actors in terms of actor selection. When provided - remote messaging and remote actor selection is possible
* @return
* instantiated actor system
*/
def apply(sysName: String, configFile: Option[File] = None): Task[ActorSystem] =
for {
initActorRefMap <- Ref.make(Map.empty[String, Actor[Any]])
config <- retrieveConfig(configFile)
remoteConfig <- retrieveRemoteConfig(sysName, config)
actorSystem <- ZIO.attempt(new ActorSystem(sysName, config, remoteConfig, initActorRefMap, parentActor = None))
_ <- ZIO
.succeed(remoteConfig)
.flatMap(_.fold[Task[Unit]](ZIO.unit)(c => actorSystem.receiveLoop(c.addr, c.port)))
} yield actorSystem
}

/**
* Type representing running instance of actor system provisioning actor herding, remoting and actor creation and
* selection.
*/
final class ActorSystem private[actors] (
override private[actors] val actorSystemName: String,
override private[actors] val config: Option[String],
private val remoteConfig: Option[RemoteConfig],
private val initActorRefMap: Ref[Map[String, Actor[Any]]],
private val parentActor: Option[String]
) extends BaseActorSystem(actorSystemName, config, remoteConfig, parentActor) {

override private[actors] def refActorMap[F[+_]]: Ref[Map[String, Actor[F]]] =
initActorRefMap.asInstanceOf[Ref[Map[String, Actor[F]]]]

override private[actors] def newActorSystem[F[+_]](
actorSystemName: String,
config: Option[String],
remoteConfig: Option[RemoteConfig],
refActorMap: Ref[Map[String, Actor[F]]],
parentActor: Option[String]
): ActorSystem =
new ActorSystem(
actorSystemName,
config,
remoteConfig,
refActorMap.asInstanceOf[Ref[Map[String, Actor[Any]]]],
parentActor
)

override private[actors] def newChildrenRefSet[F[+_]]: UIO[Ref[Set[ActorRef[F]]]] =
Ref.make(Set.empty[ActorRef[F]])

override private[actors] def newContext[F[+_]](
path: String,
derivedSystem: ActorSystem,
childrenSet: Ref[Set[ActorRef[F]]]
): Context = new Context(path, derivedSystem, childrenSet.asInstanceOf[Ref[Set[ActorRef[Any]]]])
}
16 changes: 16 additions & 0 deletions actors/src/main/scala-2/zio/actors/Context.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package zio.actors

import zio.Ref

/**
* Context for actor used inside Stateful which provides self actor reference and actor creation/selection API
*/
final class Context private[actors] (
private val path: String,
private val actorSystem: ActorSystem,
private val initChildrenRef: Ref[Set[ActorRef[Any]]]
) extends BaseContext(path, actorSystem) {

private[actors] def childrenRef[F[+_]]: Ref[Set[ActorRef[F]]] = initChildrenRef.asInstanceOf[Ref[Set[ActorRef[F]]]]

}
76 changes: 76 additions & 0 deletions actors/src/main/scala-3/zio/actors/ActorSystem.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package zio.actors

import zio.actors.ActorSystemUtils.*
import zio.actors.ActorsConfig.*
import zio.{ Ref, Task, UIO, ZIO }

import java.io.*

/**
* Object providing constructor for Actor System with optional remoting module.
*/
object ActorSystem {

/**
* Constructor for Actor System
*
* @param sysName
* \- Identifier for Actor System
* @param configFile
* \- Optional configuration for a remoting internal module. If not provided the actor system will only handle local
* actors in terms of actor selection. When provided - remote messaging and remote actor selection is possible
* @return
* instantiated actor system
*/
def apply(sysName: String, configFile: Option[File] = None): Task[ActorSystem] =
for {
initActorRefMap <- Ref.make(Map.empty[String, Actor[?]])
config <- retrieveConfig(configFile)
remoteConfig <- retrieveRemoteConfig(sysName, config)
actorSystem <- ZIO.attempt(new ActorSystem(sysName, config, remoteConfig, initActorRefMap, parentActor = None))
_ <- ZIO
.succeed(remoteConfig)
.flatMap(_.fold[Task[Unit]](ZIO.unit)(c => actorSystem.receiveLoop(c.addr, c.port)))
} yield actorSystem
}

/**
* Type representing running instance of actor system provisioning actor herding, remoting and actor creation and
* selection.
*/
final class ActorSystem private[actors] (
override private[actors] val actorSystemName: String,
override private[actors] val config: Option[String],
private val remoteConfig: Option[RemoteConfig],
private val initActorRefMap: Ref[Map[String, Actor[?]]],
private val parentActor: Option[String]
) extends BaseActorSystem(actorSystemName, config, remoteConfig, parentActor) {

override private[actors] def refActorMap[F[+_]]: Ref[Map[String, Actor[F]]] =
initActorRefMap.asInstanceOf[Ref[Map[String, Actor[F]]]]

override private[actors] def newActorSystem[F[+_]](
actorSystemName: String,
config: Option[String],
remoteConfig: Option[RemoteConfig],
refActorMap: Ref[Map[String, Actor[F]]],
parentActor: Option[String]
): ActorSystem =
new ActorSystem(
actorSystemName,
config,
remoteConfig,
refActorMap.asInstanceOf[Ref[Map[String, Actor[?]]]],
parentActor
)

override private[actors] def newChildrenRefSet[F[+_]]: UIO[Ref[Set[ActorRef[F]]]] =
Ref.make(Set.empty[ActorRef[F]])

override private[actors] def newContext[F[+_]](
path: String,
derivedSystem: ActorSystem,
childrenSet: Ref[Set[ActorRef[F]]]
): Context = new Context(path, derivedSystem, childrenSet.asInstanceOf[Ref[Set[ActorRef[?]]]])

}
16 changes: 16 additions & 0 deletions actors/src/main/scala-3/zio/actors/Context.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package zio.actors

import zio.Ref

/**
* Context for actor used inside Stateful which provides self actor reference and actor creation/selection API
*/
final class Context private[actors] (
private val path: String,
private val actorSystem: ActorSystem,
private val initChildrenRef: Ref[Set[ActorRef[?]]]
) extends BaseContext(path, actorSystem) {

override private[actors] def childrenRef[F[+_]]: Ref[Set[ActorRef[F]]] =
initChildrenRef.asInstanceOf[Ref[Set[ActorRef[F]]]]
}
56 changes: 32 additions & 24 deletions actors/src/main/scala/zio/actors/Actor.scala
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
package zio.actors

import zio.actors.Actor.PendingMessage
import zio.{ Supervisor => _, _ }
import zio.actors.Actor.PendingMessageWrapper
import zio.{ Chunk, Promise, Queue, RIO, Ref, Task, URIO }

object Actor {

private[actors] type PendingMessage[F[_], A] = (F[A], Promise[Throwable, A])
private[actors] final case class PendingMessageWrapper[F[_], A](value: PendingMessage[F, A])

/**
* Description of actor behavior (can act as FSM)
*
* @tparam R environment type
* @tparam S state type that is updated every message digested
* @tparam F message DSL
* @tparam R
* environment type
* @tparam S
* state type that is updated every message digested
* @tparam F
* message DSL
*/
trait Stateful[R, S, -F[+_]] extends AbstractStateful[R, S, F] {

/**
* Override method triggered on message received
*
* @param state available for this method
* @param msg - message received
* @param context - provisions actor's self (as ActorRef) and actors' creation and selection
* @tparam A - domain of return entities
* @return effectful result
* @param state
* available for this method
* @param msg
* \- message received
* @param context
* \- provisions actor's self (as ActorRef) and actors' creation and selection
* @tparam A
* \- domain of return entities
* @return
* effectful result
*/
def receive[A](state: S, msg: F[A], context: Context): RIO[R, (S, A)]

Expand Down Expand Up @@ -53,15 +62,14 @@ object Actor {

for {
state <- Ref.make(initial)
queue <- Queue.bounded[PendingMessage[F, _]](mailboxSize)
queue <- Queue.bounded[PendingMessageWrapper[F, _]](mailboxSize)
_ <- (for {
t <- queue.take
_ <- process(t, state)
} yield ()).forever.fork
t <- queue.take
_ <- process(t.value, state)
} yield ()).forever.fork
} yield new Actor[F](queue)(optOutActorSystem)
}
}

private[actors] trait AbstractStateful[R, S, -F[+_]] {

private[actors] def makeActor(
Expand All @@ -77,28 +85,28 @@ object Actor {

}

private[actors] final class Actor[-F[+_]](
queue: Queue[PendingMessage[F, _]]
private[actors] final class Actor[-Req[+_]](
queue: Queue[PendingMessageWrapper[Req, _]]
)(optOutActorSystem: () => Task[Unit]) {
def ?[A](fa: F[A]): Task[A] =
def ?[Res](fa: Req[Res]): Task[Res] =
for {
promise <- Promise.make[Throwable, A]
_ <- queue.offer((fa, promise))
promise <- Promise.make[Throwable, Res]
_ <- queue.offer(PendingMessageWrapper((fa, promise)))
value <- promise.await
} yield value

def !(fa: F[_]): Task[Unit] =
def !(fa: Req[Any]): Task[Unit] =
for {
promise <- Promise.make[Throwable, Any]
_ <- queue.offer((fa, promise))
_ <- queue.offer(PendingMessageWrapper((fa, promise)))
} yield ()

def unsafeOp(command: Command): Task[Any] =
command match {
case Command.Ask(msg) =>
this ? msg.asInstanceOf[F[_]]
this ? msg.asInstanceOf[Req[Any]]
case Command.Tell(msg) =>
this ! msg.asInstanceOf[F[_]]
this ! msg.asInstanceOf[Req[Any]]
case Command.Stop =>
this.stop
}
Expand Down
Loading

0 comments on commit bff7ccf

Please sign in to comment.