{"id":1,"date":"2019-04-07T14:44:08","date_gmt":"2019-04-07T14:44:08","guid":{"rendered":"http:\/\/localhost:8322\/?p=1"},"modified":"2020-08-10T18:02:59","modified_gmt":"2020-08-10T18:02:59","slug":"hello-world","status":"publish","type":"post","link":"https:\/\/www.oreineke.dev\/?p=1","title":{"rendered":"Akka Typed (with Scala)"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">What is Akka?<\/h2>\n\n\n\n<p><a href=\"https:\/\/akka.io\">Akka <\/a>is a framework for writing message driven, scalable, error resilient applications, while making working with concurrency easy. This is achieved by modeling applications around the concept of &#8220;actors&#8221;. <\/p>\n\n\n\n<p>Actors are entities that communicate with each other through messages. When an actor receives a message, it can react by <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>changing its internal state, <\/li><li>creating new actors, and <\/li><li>sending out messages to actors.<\/li><\/ul>\n\n\n\n<p>Multiple actors typically run in parallel, but the business logic within each actor is always executed single threaded, thereby avoiding complications that normally arise from concurrency.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Akka Typed<\/h2>\n\n\n\n<p>However, until the advent of <a href=\"https:\/\/doc.akka.io\/docs\/akka\/current\/typed\/index.html\">Akka Typed<\/a>, messages passed between actors have been untyped: You have been able to send any kind of message to any actor without the compiler being able to assert if the receiving actor is able to handle the message. This prevented detecting errors during compilation and made reasoning about actor driven applications difficult at times.<\/p>\n\n\n\n<p>With Akka Typed, you can now specify which message types an actor is able to handle and the compiler will complain about mismatching message types sent to an actor. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">An Example<\/h2>\n\n\n\n<p>The following is an example that shows the new Akka typed API in action (you can view and download the complete source <a href=\"https:\/\/git.oreineke.dev\/olafr\/akka-typed-scala-java\">here<\/a>):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: scala; title: ; notranslate\" title=\"\">\npackage dev.oreineke.akka.typed.example\n\nimport akka.actor.typed.ActorSystem\nimport akka.actor.typed.scaladsl.Behaviors\n\nobject Application extends App {\n  \/\/ 1) define the message type &quot;Message&quot;:\n  sealed trait Message\n  final case class Greet(name: String) extends Message\n  final object Stop extends Message\n\n  \/\/ 2) define the actor behavior (inluding the message type &quot;Message&quot; it can handle!):\n  val readyToGreet = Behaviors.receive&#x5B;Message] { (context, message) =&gt;\n    message match {\n      case Greet(name) =&gt;\n        context.log.info(s&quot;Hello $name!!!&quot;)\n        Behaviors.same\n      case Stop =&gt;\n        context.log.info(&quot;Goodbye!&quot;)\n        Behaviors.stopped\n    }\n  }\n\n  \/\/ 3) create the actor:\n  val greeter = ActorSystem(readyToGreet, &quot;Greeter&quot;)\n\n  \/\/ 4) send a few messages to the actor:\n  greeter ! Greet(&quot;Peter&quot;)\n  greeter ! Greet(&quot;Paul&quot;)\n  greeter ! Greet(&quot;Marry&quot;)\n  greeter ! Stop\n\n  \/\/ 5) the following would already fail during compilation\n  \/\/  greeter ! &quot;Eat this&quot;\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Explanation<\/h2>\n\n\n\n<p>After defining the message type the actor is willing to accept in the <code>Message<\/code> trait,<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: scala; title: ; notranslate\" title=\"\">\n  sealed trait Message\n  final case class Greet(name: String) extends Message\n  final object Stop extends Message\n<\/pre><\/div>\n\n\n<p>an actor <code>Behavior<\/code> named <code>readyToGreet<\/code> is defined:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: scala; title: ; notranslate\" title=\"\">\n  val readyToGreet = Behaviors.receive&#x5B;Message] { (context, message) =&gt;\n    message match {\n      case Greet(name) =&gt;\n        context.log.info(s&quot;Hello $name!!!&quot;)\n        Behaviors.same\n      case Stop =&gt;\n        context.log.info(&quot;Goodbye!&quot;)\n        Behaviors.stopped\n    }\n  }\n<\/pre><\/div>\n\n\n<p>Note that, to define the actor behavior <code>readyToGreet<\/code>, a typed factory method <code>Behaviors.receive[Message]<\/code> is used. It expects a function mapping the received message of type <code>Message<\/code> to a new <code>Behavior<\/code>. For the returned <code>Behavior<\/code>, instead of defining new behaviors, predefined factory methods are used to generate special return values: <code>Behaviors.same<\/code> to cause the current behavior to stay active, and <code>Behavior.stop<\/code> to cause the actor to die.<\/p>\n\n\n\n<p>Finally, <code>ActorSystem<\/code>  is called to create an actor with the <code>Behavior<\/code> <code>readyToGreet<\/code> (along with a name for easy actor identification):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: scala; title: ; notranslate\" title=\"\">\n  val greeter = ActorSystem(readyToGreet, &quot;Greeter&quot;)\n<\/pre><\/div>\n\n\n<p>At this point, the actor <code>greeter<\/code> is ready to receive massages of type <code>Message<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: scala; title: ; notranslate\" title=\"\">\n  greeter ! Greet(&quot;Peter&quot;)\n  greeter ! Greet(&quot;Paul&quot;)\n  greeter ! Greet(&quot;Marry&quot;)\n  greeter ! Stop\n<\/pre><\/div>\n\n\n<p>If we would have tried to send a message of type <code>String<\/code> to the actor, the compiler would have noticed the error:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: scala; title: ; notranslate\" title=\"\">\n  greeter ! &quot;Eat this&quot; \/\/ this will fail during compilation\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>What is Akka? Akka is a framework for writing message driven, scalable, error resilient applications, while making working with concurrency easy. This is achieved by modeling applications around the concept of &#8220;actors&#8221;. Actors are entities that communicate with each other through messages. When an actor receives a message, it can react by changing its internal [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"0","ocean_second_sidebar":"0","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"0","ocean_custom_header_template":"0","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"0","ocean_menu_typo_font_family":"0","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"0","osh_disable_topbar_sticky":"default","osh_disable_header_sticky":"default","osh_sticky_header_style":"default","osh_sticky_header_effect":"","osh_custom_sticky_logo":0,"osh_custom_retina_sticky_logo":0,"osh_custom_sticky_logo_height":0,"osh_background_color":"","osh_links_color":"","osh_links_hover_color":"","osh_links_active_color":"","osh_links_bg_color":"","osh_links_hover_bg_color":"","osh_links_active_bg_color":"","osh_menu_social_links_color":"","osh_menu_social_hover_links_color":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"off","ocean_gallery_id":[],"footnotes":""},"categories":[4,8],"tags":[3,2],"class_list":["post-1","post","type-post","status-publish","format-standard","hentry","category-akka","category-scala","tag-akka","tag-scala","entry"],"categories_names":["Akka","Scala"],"post_class":[["post-1","post","type-post","status-publish","format-standard","hentry","category-akka","category-scala","tag-akka","tag-scala","entry"]],"author_avatar":["<img alt='' src='https:\/\/secure.gravatar.com\/avatar\/a57dd6e6879c288f9d7c2e6b98faed481a067e5e155cc409952ac7e08d656a28?s=96&#038;d=mm&#038;r=g' srcset='https:\/\/secure.gravatar.com\/avatar\/a57dd6e6879c288f9d7c2e6b98faed481a067e5e155cc409952ac7e08d656a28?s=192&#038;d=mm&#038;r=g 2x' class='avatar avatar-96 photo' height='96' width='96' loading='lazy' decoding='async'\/>"],"featured_video":null,"_links":{"self":[{"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=\/wp\/v2\/posts\/1","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1"}],"version-history":[{"count":35,"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":236,"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions\/236"}],"wp:attachment":[{"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.oreineke.dev\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}