Search code examples
f#akka.netionide

How to include Akka.net framework for F# in VSCode


I am trying to use Akka.NET for F# in VSCode using this example I found on the internet.

Code

// ActorSayHello.fsx
#time "on"
// #load "Bootstrap.fsx"

open System
open Akka.Actor
open Akka.Configuration
open Akka.FSharp
open Akka.TestKit

// #Using Actor
// Actors are one of Akka's concurrent models.
// An Actor is a like a thread instance with a mailbox. 
// It can be created with system.ActorOf: use receive to get a message, and <! to send a message.
// This example is an EchoServer which can receive messages then print them.

let system = ActorSystem.Create("FSharp")

type EchoServer =
    inherit Actor

    override x.OnReceive message =
        match message with
        | :? string as msg -> printfn "Hello %s" msg
        | _ ->  failwith "unknown message"

let echoServer = system.ActorOf(Props(typedefof<EchoServer>, Array.empty))

echoServer <! "F#!"

system.Shutdown()

But I am getting this error ActorSayHello.fsx(6,6): error FS0039: The namespace or module 'Akka' is not defined.

I have configured ionide plugin in VScode and am able to run F# without Akka.NET. I installed Akka.NET using the following command

dotnet add package Akka.FSharp --version 1.4.10

The library got added automatically added to .fsproj file. This is the output of the command

Command Output

Any help would be greatly appreciated. Thank you!


Solution

  • Since you are using a script file it doesn't contain any project reference. Instead you can use nuget references directly from the script!

    #r "nuget: Akka.FSharp" 
    #r "nuget: Akka.TestKit" 
    

    Another caveat that might occur is that F# interactive needs a --langversion:preview flag to be able to use nuget references. Setting "FSharp.fsiExtraParameters": ["--langversion:preview"] in the VSCode settings.json did the trick for me.

    And the last bit that I had to change to make it compile was to replace system.Shutdown() with system.Terminate() because Shutdown method was deprecated and removed.

    Here is the full listing with changes mentioned above:

    // ActorSayHello.fsx
    #time "on"
    #r "nuget: Akka.FSharp" 
    #r "nuget: Akka.TestKit" 
    // #load "Bootstrap.fsx"
    
    open System
    open Akka.Actor
    open Akka.Configuration
    open Akka.FSharp
    open Akka.TestKit
    
    // #Using Actor
    // Actors are one of Akka's concurrent models.
    // An Actor is a like a thread instance with a mailbox. 
    // It can be created with system.ActorOf: use receive to get a message, and <! to send a message.
    // This example is an EchoServer which can receive messages then print them.
    
    let system = ActorSystem.Create("FSharp")
    
    type EchoServer =
        inherit Actor
    
        override x.OnReceive message =
            match message with
            | :? string as msg -> printfn "Hello %s" msg
            | _ ->  failwith "unknown message"
    
    let echoServer = system.ActorOf(Props(typedefof<EchoServer>, Array.empty))
    
    echoServer <! "F#!"
    
    system.Terminate()
    

    And the result looks like this on my machine:

    Real: 00:00:00.000, ЦП: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
    namespace FSI_0012.Project
    
    Hello F#!
    Real: 00:00:00.007, ЦП: 00:00:00.000, GC gen0: 1, gen1: 0, gen2: 0
    val system : ActorSystem = akka://FSharp
    type EchoServer =
      class
        inherit Actor
        override OnReceive : message:obj -> unit
      end
    val echoServer : IActorRef = [akka://FSharp/user/$a#989929929]
    val it : Threading.Tasks.Task