I'm writing some networking code currently and I need to send out a large number of messages and then wait for a single response.
Given that I have a function that returns the input and output channels for a socket I have:
let resps = List.map uris ~f:(fun uri ->
let%lwt (ic,oc) = connect uri in
let%lwt () = Lwt_io.write_value oc msg in
Lwt_io.read_value ic
) in
Lwt.pick resps
My understanding of this is that pick should cancel any ongoing requests after it has a fulfilled promise in resps. The issue is that if any of those connections fails/is refused, an exception is raised Unix.ECONNREFUSED.
My question is what is the correct semantics to force Lwt.pick to ignore the exceptions?
Options I've thought of so far are to catch the
exception explicity in the requests:
let resps = List.map uris ~f:(fun uri ->
try
let%lwt (ic,oc) = connect uri in
let%lwt () = Lwt_io.write_value oc msg in
Lwt_io.read_value ic
with Unix_error (e,_,_) -> ...
) in
Lwt.pick resps
But I'm not sure under what conditions the Lwt.pick will view those promises are rejected?
Update: I'm now handling the errors with cancellable, unfulfillable promises:
fst ## Lwt.task ()
This feels hacky but seems to work so far.
Handling the exception explicitly is right. Lwt promises are rejected when you either reject them explicitly (using Lwt.fail), or when an exception is caught by Lwt, in a callback that should have returned a promise (like the one you would pass to Lwt.bind).
However, for handling exceptions in code that calls into Lwt, you have to use try%lwt instead of the plain try.
Related
I have the following source queue definition.
lazy val (processMessageSource, processMessageQueueFuture) =
peekMatValue(
Source
.queue[(ProcessMessageInputData, Promise[ProcessMessageOutputData])](5, OverflowStrategy.dropNew))
def peekMatValue[T, M](src: Source[T, M]): (Source[T, M], Future[M]) {
val p = Promise[M]
val s = src.mapMaterializedValue { m =>
p.trySuccess(m)
m
}
(s, p.future)
}
The Process Message Input Data Class is essentially an artifact that is created when a caller calls a web server endpoint, which is hooked upto this stream (i.e. the service endpoint's business logic puts messages into this queue). The Promise of process message out is something that is completed downstream in the sink of the application, and the web server then has an on complete callback on this future to return the response back.
There are also other sources of ingress into this stream.
Now the buffer may be backed up since the other source may overload the system, thereby triggering stream back pressure. The existing code just drops the new message. But I still want to complete the process message output promise to complete with an exception stating something like "Throttled".
Is there a mechanism to write a custom overflow strategy, or a post processing on the overflowed element that allows me to do this?
According to https://github.com/akka/akka/blob/master/akkastream/src/main/scala/akka/stream/impl/QueueSource.scala#L83
dropNew would work just fine. On clients end it would look like.
processMessageQueue.offer(in, pr).foreach { res =>
res match {
case Enqueued => // Code to handle case when successfully enqueued.
case Dropped => // Code to handle messages that are dropped since the buffier was overflowing.
}
}
I am trying to test a MailboxProcessor in F#. I want to test that the function f I am giving is actually executed when posting a message.
The original code is using Xunit, but I made an fsx of it that I can execute using fsharpi.
So far I am doing this :
open System
open FSharp
open System.Threading
open System.Threading.Tasks
module MyModule =
type Agent<'a> = MailboxProcessor<'a>
let waitingFor timeOut (v:'a)=
let cts = new CancellationTokenSource(timeOut|> int)
let tcs = new TaskCompletionSource<'a>()
cts.Token.Register(fun (_) -> tcs.SetCanceled()) |> ignore
tcs ,Async.AwaitTask tcs.Task
type MyProcessor<'a>(f:'a->unit) =
let agent = Agent<'a>.Start(fun inbox ->
let rec loop() = async {
let! msg = inbox.Receive()
// some more complex should be used here
f msg
return! loop()
}
loop()
)
member this.Post(msg:'a) =
agent.Post msg
open MyModule
let myTest =
async {
let (tcs,waitingFor) = waitingFor 5000 0
let doThatWhenMessagepostedWithinAgent msg =
tcs.SetResult(msg)
let p = new MyProcessor<int>(doThatWhenMessagepostedWithinAgent)
p.Post 3
let! result = waitingFor
return result
}
myTest
|> Async.RunSynchronously
|> System.Console.WriteLine
//display 3 as expected
This code works, but it does not look fine to me.
1) is the usage of TaskCompletionSource normal in f# or is there some dedicated stuff to allow me waiting for a completion?
2) I am using a second argument in the waitingFor function in order to contraint it, I know I could use a type MyType<'a>() to do it, is there another option? I would rather not use a new MyType that I find cumbersome.
3) Is there any other option to test my agent than doing this? the only post I found so far about the subject is this blogpost from 2009 http://www.markhneedham.com/blog/2009/05/30/f-testing-asynchronous-calls-to-mailboxprocessor/
This is a tough one, I've been trying to tackle this for some time as well. This is what I found so far, it's too long for a comment but I'd hesitate to call it a full answer either...
From simplest to most complex, depends really how thoroughly you want to test, and how complex is the agent logic.
Your solution may be fine
What you have is fine for small agents whose only role is to serialize access to an async resource, with little or no internal state handling. If you provide the f as you do in your example, you can be pretty sure it will be called in a relatively short timeout of few hundred milliseconds. Sure, it seems clunky and it's double the size of code for all the wrappers and helpers, but those can be reused it you test more agents and/or more scenarios, so the cost gets amortized fairly quickly.
The problem I see with this is that it's not very useful if you also want to verify more than than the function was called - for example the internal agent state after calling it.
One note that's applicable to other parts of the response as well: I usually start agents with a cancellation token, it makes both production and testing life cycle easier.
Use Agent reply channels
Add AsyncReplyChannel<'reply> to the message type and post messages using PostAndAsyncReply instead of Post method on the Agent. It will change your agent to something like this:
type MyMessage<'a, 'b> = 'a * AsyncReplyChannel<'b>
type MyProcessor<'a, 'b>(f:'a->'b) =
// Using the MyMessage type here to simplify the signature
let agent = Agent<MyMessage<'a, 'b>>.Start(fun inbox ->
let rec loop() = async {
let! msg, replyChannel = inbox.Receive()
let! result = f msg
// Sending the result back to the original poster
replyChannel.Reply result
return! loop()
}
loop()
)
// Notice the type change, may be handled differently, depends on you
member this.Post(msg:'a): Async<'b> =
agent.PostAndAsyncReply(fun channel -> msg, channel)
This may seem like an artificial requirement for the agent "interface", but it's handy to simulate a method call and it's trivial to test - await the PostAndAsyncReply (with a timeout) and you can get rid of most of the test helper code.
Since you have a separate call to the provided function and replyChannel.Reply, the response can also reflect the agent state, not just the function result.
Black-box model-based testing
This is what I'll talk about in most detail as I think it's most general.
In case the agent encapsulates more complex behavior, I found it handy to skip testing individual messages and use model-based tests to verify whole sequences of operations against a model of expected external behavior. I'm using FsCheck.Experimental API for this:
In your case this would be doable, but wouldn't make much sense since there is no internal state to model. To give you an example what it looks like in my particular case, consider an agent which maintains client WebSocket connections for pushing messages to the clients. I can't share the whole code, but the interface looks like this
/// For simplicity, this adapts to the socket.Send method and makes it easy to mock
type MessageConsumer = ArraySegment<byte> -> Async<bool>
type Message =
/// Send payload to client and expect a result of the operation
| Send of ClientInfo * ArraySegment<byte> * AsyncReplyChannel<Result>
/// Client connects, remember it for future Send operations
| Subscribe of ClientInfo * MessageConsumer
/// Client disconnects
| Unsubscribe of ClientInfo
Internally the agent maintains a Map<ClientInfo, MessageConsumer>.
Now for testing this, I can model the external behavior in terms of informal specification like: "sending to a subscribed client may succeed or fail depending on the result of calling the MessageConsumer function" and "sending to an unsubscribed client shouldn't invoke any MessageConsumer". So I can define types for example like these to model the agent.
type ConsumerType =
| SucceedingConsumer
| FailingConsumer
| ExceptionThrowingConsumer
type SubscriptionState =
| Subscribed of ConsumerType
| Unsubscribed
type AgentModel = Map<ClientInfo, SubscriptionState>
And then use FsCheck.Experimental to define the operations of adding and removing clients with differently successful consumers and trying to send data to them. FsCheck then generates random sequences of operations and verifies the agent implementation against the model between each steps.
This does require some additional "test only" code and has a significant mental overhead at the beginning, but lets you test relatively complex stateful logic. What I particularly like about this is that it helps me test the whole contract, not just individual functions/methods/messages, the same way that property-based/generative testing helps test with more than just a single value.
Use Actors
I haven't gone that far yet, but what I've also heard as an alternative is using for example Akka.NET for full-fledged actor model support, and use its testing facilities which let you run agents in special test contexts, verify expected messages and so on. As I said, I don't have first-hand experience, but seems like a viable option for more complex stateful logic (even on a single machine, not in a distributed multi-node actor system).
I am struggling at the check and validate function for Lwt_pool.create and have some questions here.
val create :
int ->
?check:('a -> (bool -> unit) -> unit) ->
?validate:('a -> bool Lwt.t) -> (unit -> 'a Lwt.t) -> 'a t
First of all, let me describe the background of my usage.
I wish to use Lwt_pool to manage a pool of database connections. The database is MongoDB and the driver was made by myself (Mongo.ml). The driver is actually simple that it is just a TCP (Unix.file_descr) connection to the MongoDB server and send requests / receive responses with the server.
`create n ?check ?validate f` creates a new pool with at most n members. f is the function to use to create a new pool member.
An element of the pool is validated by the optional validate function before its Lwt_pool.use. Invalid elements are re-created.
The optional function check is called after a use of an element failed. It must call its argument excatly one with true if the pool member is still valid and false otherwise.
above is the documentation for create
So here are my questions:
From the doc, I understand validate is to validate the connection before using it.
so my first question is How can I check the availability of a Unix.file_descr? I only know that in order to check it, I have send something through it, right? But if I send something through my connection in order to check, then I guess it would be urgly and I anyway want to send something out via Lwt_pool.use, why bother do similar things before use?
My second question is about check.
So check will be used after use. From the doc, I really can't understand. check is a function which take a my_db_connection (in my case) and a (fun b -> unit) as parameter. Who will provide (fun b -> unit)? Does Lwt_pool itself has such a function? or I should provide it? To do what then?
thanks
I don't know anything about Lwt, but one thing to do is to wait to use a validate function until you see why you would need it. That's why it's an optional parameter (I suspect).
One thing you can do with a Unix file descriptor is to figure out whether it's attached to a network socket:
let is_a_socket fd = (Unix.fstat fd).st_kind = S_SOCK
Maybe this will be useful, though someone with Lwt experience can probably give a better answer.
The Ocsigen/Eliom tutorial starts with an example of an application that serves up "Hello, world!" as HTML:
open Eliom_content.Html5.D
let main_service =
Eliom_registration.Html5.register_service
~path:["graff"]
~get_params:Eliom_parameter.unit
(fun () () ->
Lwt.return
(html
(head (title (pcdata "Page title")) [])
(body [h1 [pcdata "Graffiti"]])))
How would one serve this as JSON instead? Specifically, how does one register a JSON service, and what library/combinators should be used to generate/serialize the JSON (js_of_ocaml?)?
If you want to communicate with a client side Eliom program, you do not need to serialize yourself your data to JSON. Serialization/Deserialization of any OCaml type is done automatically by Eliom. Just use OCaml services (or, simpler: server functions and call the function from your OCaml client side program).
If you want to use your own JSON format, you need to have your own serialisation function to JSON (or for example to use some ocaml library like json-wheel to generate JSON). In that case, you can register your service using Eliom_registration.String instead of Eliom_registration.Html5. The handler function must return the JSON value as a string, and a the content-type.
It is even possible to define yourself your own registration module, to be used instead of Eliom_registration.String. Thus, you can use an OCaml representation of the JSON value (and you don't call the serializer yourself). Have a look on how modules like Eliom_registration.String are implemented to know how to do that.
I'm not sure to understand what you want to do, but, about JSON, you can use "deriving" (cf. Deriving_Json) to create a JSON type by using an OCaml type like this:
type deriving_t = (string * string) deriving (Json)
This will create the JSON type corresponding to the OCaml type.
Here the way of using this type to communicate with the server (if you don't know server functions, here the documentation about it and about client values on server side):
(* first you have to create a server function (this allowed the client to call a function from the server *)
let json_call =
server_function
Json.t<deriving_t>
(fun (a,b) ->
Lwt.return (print_endline ("log on the server: "^a^b)))
(* let say that distillery has already generate all the needed stuff (main_service, Foobar_app, etc..) *)
let () =
Foobar_app.register
~service:main_service
(fun () () ->
{unit{
(* here I call my server function by using ocaml types directly, it will be automatically serialize *)
ignore (%json_call ("hello", "world"))
}};
Lwt.return
(Eliom_tools.F.html
~title:"foobar"
~css:[["css";"foobar.css"]]
Html5.F.(body [
h2 [pcdata "Welcome from Eliom's distillery!"];
])))
If you want to use some client/server communication, you should take a look to Eliom_bus, Eliom_comet or Eliom_react.
(sorry, I can't make more than 2 links :) but you will find the documentation on the ocsigen.org website).
Hope that can help you.
I have been slowly examining all of the features that F# brings to the table. One that has particularly piqued my interest is the MailboxProcessor.
The equivalent of this in C# would most likely use locks. Can we consider the MailboxProcessor as a replacement for locks?
In the following example, am I doing
anything particularly naive or can
you see anything that might be
improved?
module Tcp =
open System
open System.Collections.Generic
open System.Net
open System.Net.Sockets
open System.Threading
type SocketAsyncMessage =
| Get of AsyncReplyChannel<SocketAsyncEventArgs>
| Put of SocketAsyncEventArgs
| Dispose of AsyncReplyChannel<MailboxProcessor<SocketAsyncMessage>>
type SocketAsyncEventArgsPool(size:int) =
let agent =
lazy(MailboxProcessor.Start(
(fun inbox ->
let references = lazy(new List<SocketAsyncEventArgs>(size))
let idleReferences = lazy(new Queue<SocketAsyncEventArgs>(size))
let rec loop () =
async {
let! message = inbox.Receive()
match message with
| Get channel ->
if idleReferences.Value.Count > 0 then
channel.Reply(idleReferences.Value.Dequeue())
else
let args = new SocketAsyncEventArgs()
references.Value.Add args
channel.Reply args
return! loop()
| Put args ->
if args = null then
nullArg "args"
elif references.Value.Count < size then
idleReferences.Value.Enqueue args
else
if not(references.Value.Remove args) then
invalidOp "Reference not found."
args.Dispose()
return! loop()
| Dispose channel ->
if references.IsValueCreated then
references.Value
|> Seq.iter(fun args -> args.Dispose())
channel.Reply inbox
}
loop())))
/// Returns a SocketAsyncEventArgs instance from the pool.
member this.Get () =
agent.Value.PostAndReply(fun channel -> Get channel)
/// Returns the SocketAsyncEventArgs instance to the pool.
member this.Put args =
agent.Value.Post(Put args)
/// Releases all resources used by the SocketAsyncEventArgsPool.
member this.Dispose () =
(this:>IDisposable).Dispose()
interface IDisposable with
member this.Dispose() =
if agent.IsValueCreated then
(agent.Value.PostAndReply(fun channel -> Dispose channel):>IDisposable).Dispose()
Mailboxes (and similar constructs) are used in programming models that don't use locks, as they're inherently built around asynchronous processing. (Lack of shared mutable state is another requirement of this model).
The Actor model can be thought of as a series of single-threaded mini-applications that communicate by sending and receiving data from each other. Each mini-application will only be run by a single thread at a time. This, combined with the lack of shared state, renders locks unnecessary.
Procedural models (and most OO code is, at its heart, procedural), use thread-level concurrency, and synchronous calls to other objects. The Actor model flips this around - calls (messages) between objects are asynchronous, but each object is completely synchronous.
I don't know enough F# to really analyze your code, frankly. It does look like you're trying to stick a synchronous-looking shell around your mailbox, and I wonder if that's really the best thing to do (vs. embracing the mailbox model fully). In your implementation, it does appear that you're using it as a replacement for a lock.
To first part of your question:
The MailboxProcessor class is a message queue running on its own thread. You may send an message
to the MailboxProcessor from any thread as asynchronously as synchronously.
Such model allows to communicate between threads through message passing instead of using locks/mutexes/ipc mechanics.