Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to Scala 3 #534

Merged
merged 48 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
5b2cc2e
build.sbt and fmt migrated
Ragge-dev Dec 29, 2023
59873c2
migrated zio-actors
Ragge-dev Dec 29, 2023
1a5cbbd
migrated zio-persistence
Ragge-dev Dec 29, 2023
9933ac8
migrated persistence-jdbc
Ragge-dev Dec 29, 2023
ce8c66c
migrated akka-interop
Ragge-dev Dec 29, 2023
83b21c8
migrated-examples
Ragge-dev Dec 29, 2023
55ba7e4
removed empty test file
Ragge-dev Dec 29, 2023
94e26bb
generated new docs
Ragge-dev Dec 29, 2023
1f50136
remove most workflows
Ragge-dev Dec 29, 2023
bddd5c5
Merge branch 'master' into scala3-migration
Ragge-dev Dec 29, 2023
32ebf0c
Revert "remove most workflows"
Ragge-dev Dec 29, 2023
182b407
Revert "generated new docs"
Ragge-dev Dec 29, 2023
0318445
reverted ! interface
Ragge-dev Dec 29, 2023
fadb90e
private val inte BuildHelper
Ragge-dev Dec 29, 2023
3f688d6
fix docs
Ragge-dev Dec 29, 2023
b0641e2
more docs warnings fixed
Ragge-dev Dec 29, 2023
ed79221
Fixes from compiler-flags, unused private functions
Ragge-dev Dec 29, 2023
84fbe01
updated README
Ragge-dev Dec 29, 2023
56bc515
type warnings fixed
Ragge-dev Jan 4, 2024
ad583aa
Fixed serialization....
Ragge-dev Jan 7, 2024
4600139
Separate classes
Ragge-dev Jan 7, 2024
520b7de
scala-2 folder
Ragge-dev Jan 7, 2024
775bdf4
Add annotation for overridden Serialization method
Ragge-dev Jan 7, 2024
214480b
formatting
Ragge-dev Jan 7, 2024
e0a9d0d
Get all versions to play together
Ragge-dev Jan 7, 2024
62a8bcd
formatting
Ragge-dev Jan 7, 2024
59bf563
genereted docs/README
Ragge-dev Jan 7, 2024
a91cc04
Added Scala 3.3.1 as CI build
Ragge-dev Jan 7, 2024
1fc75f3
Add docs again to build
Ragge-dev Jan 7, 2024
6ec9c49
formatting in scala-3 folder
Ragge-dev Jan 7, 2024
1c6bb31
fix packages
Ragge-dev Jan 7, 2024
2330daf
simplify
Ragge-dev Jan 7, 2024
6ccbb0d
Break out as much common logic as possible
Ragge-dev Jan 14, 2024
66c8473
only use refActorMap in ActorSystem, and change name to be consistent
Ragge-dev Jan 14, 2024
17fd149
Helped scala 2.12 compiler
Ragge-dev Jan 14, 2024
b8dea2d
formating
Ragge-dev Jan 14, 2024
c360a1b
BaseActorSystem private
Ragge-dev Jan 14, 2024
b4ae21a
Fix docs not compiling
Ragge-dev Jan 14, 2024
ddbd16d
Break out logic for Context class
Ragge-dev Jan 14, 2024
ac4f75a
README finds version
Ragge-dev Jan 14, 2024
d3810eb
fix website-workflow import error
Ragge-dev Jan 14, 2024
e27c89b
sbt publishLocal fails. Reverted imports to ._
Ragge-dev Jan 14, 2024
5ca9e51
removed unused file
Ragge-dev Jan 14, 2024
fc851f2
Removed more scala 3 syntax
Ragge-dev Jan 14, 2024
22d04ea
bit sloppy, reverted more imports and wildcards
Ragge-dev Jan 14, 2024
985201a
remove xSource3 flag for scala2.12
Ragge-dev Jan 14, 2024
cced3f2
Manges to move all business logic to BaseActorSystem
Ragge-dev Jan 14, 2024
573f17d
reverted akka upgrade
Ragazoor Jan 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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: ['adopt@1.8', 'adopt@1.11']
scala: ['2.12.15', '2.13.8']
scala: ['2.12.15', '2.13.8', '3.3.1']
steps:
- uses: actions/checkout@v2.3.4
- 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]]],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I see it correctly the only version-specific difference is Actor[Any] vs Actor[?] here. Is Scala 2 not compiling with ? (or _?)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct, I have made a few attempts on scala 2.13 but haven't been able to make it work... Get errors like:

private val initActorRefMap: Ref[Map[String, Actor[_]]], _$2 takes no type parameters, expected: 1
                                                   ^

I have also tried to make scala 3 compile with Actor[Any] but get errors like:

Type argument Any does not have the same kind as its bound [+_$1]

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
Loading