3
\$\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\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.