2
\$\begingroup\$

This is my first attempt at creating a small module to wrap the .NET library EasyNetQ in F# to make it more functional.

I am pretty new to F# and I would like to get feedbacks on everything: types, naming conventions, functional thinking, etc.

RabbitMQ.fs:

module RabbitMQ
    open EasyNetQ
    open System

    type BusConnection = {
        Address: string
        Port: uint16
        Username: string
        Password: string
    }

    type NamingConventions = {
        RetrieveQueueName: Type -> string -> string
        RetrieveExchangeName: Type -> string
        RetrieveErrorQueueName: MessageReceivedInfo -> string
        RetrieveErrorExchangeName: MessageReceivedInfo -> string
    }

    type Subscription<'T> = {
        Id: string
        OnMessageReceived: 'T -> unit
    }

    let private buildConnectionString (busConnection: BusConnection) =
        sprintf "host=%s:%d;username=%s;password=%s"
               busConnection.Address
               busConnection.Port
               busConnection.Username
               busConnection.Password

    let createBus (connection: BusConnection) =
        let connectionString = buildConnectionString connection
        RabbitHutch.CreateBus(connectionString)

    let publishAsync<'T> (bus: IBus) (message: 'T) = bus.PubSub.PublishAsync<'T>(message)
                                                     |> Async.AwaitTask

    let subscribeAsync<'T> (bus: IBus) (subscription: Subscription<'T>) = bus.PubSub.SubscribeAsync<'T>(subscription.Id, subscription.OnMessageReceived).AsTask()
                                                                          |> Async.AwaitTask

    let setNamingConventions (bus: IBus) (namingConventions: NamingConventions) =
        bus.Advanced.Conventions.QueueNamingConvention <- new QueueNameConvention(namingConventions.RetrieveQueueName)
        bus.Advanced.Conventions.ExchangeNamingConvention <- new ExchangeNameConvention(namingConventions.RetrieveExchangeName)
        bus.Advanced.Conventions.ErrorQueueNamingConvention <- new ErrorQueueNameConvention(namingConventions.RetrieveErrorQueueName)
        bus.Advanced.Conventions.ErrorExchangeNamingConvention <- new ErrorExchangeNameConvention(namingConventions.RetrieveErrorExchangeName)

Program.fs:


open RabbitMQ

type Message = {
    Text: string
}

[<EntryPoint>]
let main argv =
    let busConnection = {
        Address = "localhost"
        Port = 5672 |> uint16
        Username = "guest"
        Password = "guest"
    }
    let namingConventions = {
        RetrieveQueueName = fun messageType subscriptionId -> "Queue: " + (messageType.FullName + subscriptionId)
        RetrieveExchangeName = fun messageType -> "Exchange: " + messageType.FullName
        RetrieveErrorQueueName = fun messageReceivedInfo -> messageReceivedInfo.Queue + " - Error"
        RetrieveErrorExchangeName = fun messageReceivedInfo -> messageReceivedInfo.Exchange + " - Error"
    }
    use bus = createBus busConnection
    setNamingConventions bus namingConventions

    let subscription = {
        Id = "subscription_id"
        OnMessageReceived = fun (message: Message) -> printfn "%A" message
    }

    async {
        let! result = subscribeAsync<Message> bus subscription
        do! publishAsync<Message> bus {Text = "1"}
        do! publishAsync<Message> bus {Text = "2"}
        do! publishAsync<Message> bus {Text = "3"}
    } |> Async.RunSynchronously

    Console.waitPressKey

    0

Console.fs

module Console
    open System
    let waitPressKey = Console.ReadKey() |> ignore
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.