Most of my code looks like this
handle_event({publish,Publish_Msg,Publishing_Channel},State)->
Member = pg2:get_members(helpers:get_channel_name(Publishing_Channel)),
case Member of
[M|O]->
[Pid!{send,Publish_Msg}||Pid<-[M|O]];
{error,_}-> lager:info("unavailable")
end,
{ok,State};
The above handler gets called for publish event and all it does is it sends a message to a process id.
What I would like to do is create a bunch of mock Pids and and then have this event handler send data to those. And check if the data is actually received by them. Is there any way to do this with EUNIT. Or is there a better way to test event handlers?
use Common Test (1) which lets you start your gen_event per testcase/group/suite. It's powerful and well documented, and also the book Learn you some Erlang (2) has a great chapter about it.
(1): http://www.erlang.org/doc/man/common_test.html
(2): http://learnyousomeerlang.com/common-test-for-uncommon-tests
Related
I have a function
convertMsg : Msg1 -> List Msg2
where Msg1 and Msg2 are certain message types. And I would like to turn this into a function:
convertCmd : Cmd Msg1 -> Cmd Msg2
Which would for every message in the batch replace it with some messages possibly none or more than 1.
As a Haskell programmer at heart I immediately reach for a monadic bind ((>>=) in Haskell and andThen in the Elm parlance), a function with the type:
bind : (a -> Cmd b) -> Cmd a -> Cmd b
I can easily change my convertMsg to be the following:
convertMsg : msg1 -> Cmd Msg2
At which point it would be just perfect for the bind.
But looking in Platform.Cmd, there isn't such a function I can find. There's a map which is similar, but convertMsg can't really be convertMsg : Msg1 -> Msg2 since it doesn't always give back exactly one message.
Is there a way to achieve this? Is there some limitation to the Cmd type that would prevent this sort of thing?
What you're trying to do to messages, how you might, and whether it's a good plan
I promise I'll try to answer what I think you're trying to do, but first I think there's a more important thing...
You're perhaps assuming that Cmd is analogous to IO from Haskell, but Cmd is asynchronous and isn't designed to chain actions. Your update is what glues consequences to outputs:
update : Msg -> Model -> (Model,Cmd Msg)
At the end of your update, you can issue a Cmd Msg to ask elm to do something externally, usually passing it a constructor with which it can wrap its output. This output comes back to your update function.
What you don't do is chain Cmds together as you would in a monad. There's no bind for Cmd, or to put it another way, the only bind for Cmd is your update function!
Now I suppose that if you wanted to catch a MyComplexMsg : Msg and turn it into [SimpleMsg1,SimpleMsg2], you could pattern match for it in your update function, leave the model unchanged and issue a new Cmd Msg, but what command would you be running the second time?
You could certainly take a pure Msg -> List Msg function and use Cmd.map to apply it, or apply it manually in the pattern match at the beginning of update, like
update msg model = case msg of
MyComplexMsg -> myHandler [SimpleMsg1,SimpleMsg2]
...
or even go full state monad style with
update msg model0 = case msg of
MyComplexMsg ->
let
(model1,cmd1) = update SimpleMsg1 model0
(model2,cmd2) = update SimpleMsg2 model1
in
(model2,Cmd.batch [cmd1,cmd2])
to try to emulate monadic bind, but I don't know why you might ever want this, and a lot of advice in the elm literature and community is that if you're calling update from update you're probably doing it wrong. Make a separate single-purpose helper function for that stuff instead of re-running your entire program logic twice!
Let go of your need to have a monad
I suspect that what's going wrong is that you're not letting go of a monadic control flow mentality. update is where it's at. update is where you make things happen. User input and asynchronous messages are your drivers, not sequencing. Cmd is just for communicating externally. You don't plumb the results back in, the elm architecture does that for you. Just handle the result of your Cmd (which will arrive as a message) as a branch in your update and it'll all progress nicely, and if the user presses some button of their own choice without you making it happen, so be it. You can handle that too.
I worry that you're trying to write a monad transformer stack in elm, which is a bit like trying to write an object oriented programming library in haskell. Haskell doesn't do object oriented programming, and the sooner folks drop the OO thinking and let go of their need to bundle data and functions together, the sooner they're writing good haskell code. Elm doesn't do typeclasses, it does model/view/update, and does it extraordinarily well. Let go of your need to find and use a monad to control the flow of your program, and instead respond to what messages you're given. Make a Msg for something you want to happen, provide a way to trigger it appropriately in your view and then handle it in your update.
When should one message become three messages?
If one of your messages is really three messages, why isn't it three messages already? If it's just that in response to that particular message, you just need to do three things to your model and issue five commands, why not just have one message and get update to do those three things to your model using pure code and issue the five commands in a batch?
If you need to log the successful login, then get the user's photo, then query the database for their recent activity, then display it all, then I disagree about the immediateness, and they're all asynchronous. You can issue commands to do each of those things in a batch, and when the responses come back you will need to separately deal with each - update your model with the image when it arrives, with the list of recent activity when it arrives. Once your model is in the state that the picture and the recent activity are both there you can change the view, but why not show each as soon as they're there?
Using monads sometimes trains us to think sequentially when we're doing effects programming when we needn't, but now, finally, I'll address what to do when there is a compelling need to sequence commands.
Genuinely necessary sequential commands
Perhaps there really is something sequential that you need. Maybe you have to query some data store for something before you send some request elsewhere. You still don't use a bind, you just use your update:
update msg model = case msg of
StartsMultiStageProcess userID ->
({model|multiStageProcessStatus = RequestedData}
, getDataPart1 userID PartOneReceived )
PartOneReceived userData ->
({model|multiStageProcessStatus = Fired}
, fireRockets userData.nemesis.location RocketResult)
RocketResult r -> if model.multiStageProcessStatus == Fire then
case r of
Ok UtterlyDestroyed ->
....
Ok DamagedBeyondUse ->
....
Err disappointment ->
....
...
A handy point is that if your model doesn't have the required data, it automatically won't show the missing data in the view (sum types for the win), and you can store whatever state your multistage process is in in the model.
You might prefer to put all of those messages into a new type so it becomes indented once further in the handler and won't ever be mixed with other ones in the order, like
MSPmsg msg -> case msg of
Started userId ->
...
GotPartOne userData ->
but much more likely use a helper function like MSPmsg msg -> updateMultiStageProcess.
Concluding advice
Maybe there's some great use case for delving into messages and commands and editing them that you haven't made explicit, but Cmd is opaque and all you can do is issue them and handle the resulting messages, so I'm sceptical but definitely interested.
Also in giving you update to write, it's almost like they've given you the app-specific bind to write (but it's not a functor and you absolutely do look at the data), so they've given you the keys to the Tesla. It takes a bit of getting used to but you're really going to like what happens at the traffic lights. Don't attempt to dismantle the door hinges until you've learned to drive it.
Edit: Your specific use case: inter-page communication
It turns out in chat that you're trying to get messages from one page to be usable in other pages or the overall update - sometimes one page needs to tell the app to change page and tell the new page to start an animation. I might have skipped all the advice above if I'd known that initially, but I think it's good advice for anyone coming from Haskell and I'm leaving it in!
Multiple messages
I still think it's important to accept that sometimes a single message needs to cover multiple actions, and you sort that out in your update function rather than try to create multiple messages in response to a single user action.
Lots of elm folks give the advice that your messages, rather than describing something to do like AddProduct they should describe something that happened in the past, partly because that's how messages come to you in your update so your mental model of what the elm runtime is doing is accurate, and partly because you're less likely to want to make two messages and do weird message translations when you ought to make one message.
Do multiple things in your ClickedViewOffers branch of update rather than try to make both a SwitchToOffersPage and a
AnimatePickOfTheDay message.
I'd like to point out that your idea to convert your messages and filter them somehow within the messages type is doing it in the wrong place. Filtering so that your Home page doesn't get all the messages for your Login page is something you have to do in update anyway - don't try to filter them while you're making or passing the messages. update is where it's at for deciding what to do in response to user input. Messages are for describing user input.
OK, but how do you get messages to cross the barriers between pages?!
There are a few ways to achieve this and it might be worth looking into different ways of making a Single Page Application (SPA) in Elm. I found this article by Rogério Chaves on Medium quite enlightening on the topic of various ways of organising messages from child page to parent app. He's done the TodoMVC app all the different ways in this repo A stack overflow post is better if it inlines ideas, so here we go:
Common Msg type across all pages
This can work by having a separate module for your message types which all your modules import. Messages look like ProductsMsg (UserCreatedNewProduct productRecord), as they might well do anyway, but because all the message types are global you can call another page's methods.
Individual pages also return an OutMsg from their update function
Use better names than these (eg Login.Msg rather than LoginMsg), but...
loginPageUpdate : LoginMsg -> LoginModel -> (LoginModel,Cmd LoginMsg,OutMsgFromLogin)
update : GlobalMsg -> GlobalModel -> (GlobalModel,Cmd GlobalMsg)
update msg model = case msg of
LoginMsg loginMsg ->
let (newLoginModel,cmd,outMsgFromLogin) = loginPageUpdate loginMsg model.loginModel
in
...
(You'd need NoOp :: OutMsgFromLogin or use Maybe OutMsgFromLogin there. I'm not a fan of NoOp. It's terribly tempting to use it for unimplemented features, and it's the king of all divorced-from-user-intentions messages that doesn't explain why you ought to do nothing or how you came to write something where you generated a purposeless message. I think it's a code smell that there's a better way of writing something.)
Have a record of messages that you later use to translate your page's Msgs messages into global messages.
(Again, use better domain-specific names, I'm trying to convey usage in my names.)
type LoginMessagesRecord globalMsg =
{ internalLoginMsgTag : LoginMsg -> globalMsg
, loginSucceeded : User -> globalMsg
, loginFailed : globalMsg
, newUserSuccessfullyRegistered : User -> globalMsg
}
and in your main, you would specify these:
loginMessages : LoginMessagesRecord GlobalMsg
loginMessages =
{ internalLoginMsgTag = LocalLoginMsg
, loginSucceeded = LoginSucceeded
, loginFailed = LoginFailed
, newUserSuccessfullyRegistered = NewUserSuccessfullyRegistered
}
You can either parameterise functions in your Login code with those so they all consume a LoginMessagesRecord and produce a msg, or you can use a genuinely local message type and write a translation helper in your Login module:
type HereOrThere here there = Here here | There there
type LocalLoginMessage = EditedUserName String | EditedPassword String | ....
type MessageForElsewhere = LoggedIn User | DidNotLogIn | MadeNewAccount User
type alias LoginMsg = HereOrThere LocalLoginMessage MessageForElsewhere
loginMsgTranslator : LoginMessagesRecord msg -> LoginMsg -> msg
loginMsgTranslator
{ internalLoginMsgTag
, loginSucceeded
, loginFailed
, newUserSuccessfullyRegistered
}
loginMsg = case loginMsg of
Here msg -> internalLoginMsgTag msg
There msg -> case msg of
LoggedIn user -> loginSucceeded user
DidNotLogIn -> loginFailed
MadeNewAccount user -> newUserSuccessfullyRegistered user
and then you can use Html.map loginMsgTranslator loginView in your global view, or Element.map loginMsgTranslator loginView if you're using the utterly brilliant html&css-free way to write elm apps, elm-ui.
Summary / takeaway
Have a single message describing a user intention and use update to handle all the consequences.
Don't edit the messages, respond appropriately in the update
The user is in control. The runtime is in control. You're not in control. Don't generate messages yourself, just respond to them. If you're generating messages rather than the user or the runtime, you're using elm in a weird way that'll be hard.
Your program logic largely resides in update. It doesn't reside in message. Don't try to make things happen in message, just describe what the user did or what the system did in the message.
Use case statements and descriptive tags in message types to help choose which update helper function to run. It can often help to use union types to describe how local a message is. Sometimes you use a local updating function, sometimes a global one.
You might want to also read this reddit thread about scaling elm apps that Rogério Chaves references.
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 currently working on a async rest client using boost::asio::io_service.
I am trying to make the client as a some kind of service for a bigger program.
The idea is that the client will execute async http requests to a rest API, independently from the thread running the main program. So inside in the client will be another thread waiting for a request to send.
To pass the requests to the client I am using a io_service and io_service::work initialized with the io_service. I almost reused the example given on this tutorial - logger_service.hpp.
My problem is that when in the example they post a work to the service, the called handler is a simple function. In my case as I am making async calls like this
(I have done the necessary to run all the instancies of the following objects and some more in a way to be able to establish the network connection):
boost::asio::io_service io_service_;
boost::asio::io_service::work work_(io_service_); //to prevent the io_service::run() to return when there is no more work to do
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_(io_service_);
In the main program I am doing the following calls:
client.Connect();
...
client.Send();
client.Send();
...
Some client's pseudo code:
void MyClass::Send()
{
...
io_service_.post(boost::bind(&MyClass::AsyncSend, this);
...
}
void MyClass::AsyncSend()
{
...
boost::io_service::asio::async_write(socket, streamOutBuffer, boost::bind(&MyClass::handle_send, this));
...
}
void MyClass::handle_send()
{
boost::io_service::asio::async_read(socket, streamInBuffer, boost::bind(&MyClass::handle_read, this));
}
void MyClass::handle_read()
{
// ....treatment for the received data...
if(allDataIsReceived)
FireAnEvent(ReceivedData);
else
boost::io_service::asio::async_read(socket, streamInBuffer, boost::bind(&MyClass::handle_read, this));
}
As it is described in the documentation the 'post' method requests the io_service to invoke the given handler and return immediately. My question is, will be the nested handlers, for example the ::handle_send in the AsyncSend, called just after (when the http response is ready) when post() is used? Or the handlers will be called in another order different from the one defined by the order of post() calls ?
I am asking this question because when I call only once client->Send() the client seems to "work fine". But when I make 2 consecutive calls, as in the example above, the client cannot finish the first call and than goes to execute the second one and after some chaotic executions at the end the 2 operations fail.
Is there any way to do what I'm describing execute the whole async chain before the execution of another one.
I hope, I am clear enough with my description :)
hello Blacktempel,
Thank you for the given comment and the idea but however I am working on a project which demands using asynchronous calls.
In fact, as I am newbie with Boost my question and the example I gave weren't right in the part of the 'handle_read' function. I add now a few lines in the example in a way to be more clear in what situation I am (was).
In fact in many examples, may be all of them, who are treating the theme how to create an async client are very basic... All they just show how to chain the different handlers and the data treatment when the 'handle_read' is called is always something like "print some data on the screen" inside of this same read handler. Which, I think, is completely wrong when compared to real world problems!
No one will just print data and finish the execution of her program...! Usually once the data is received there is another treatment that has to start, for example FireAnEvent(). Influenced by the bad examples, I have done this 'FireAnEvent' inside the read handler, which, obviously is completely wrong! It is bad to do that because making the things like that, the "handle_read" might never exit or exit too late. If this handler does not finish, the io_service loop will not finish too. And if your further treatment demands once again to your async client to do something, this will start/restart (I am not sure about the details) the io_service loop. In my case I was doing several calls to the async client in this way. At the end I saw how the io_service was always started but never ended. Even after the whole treatment was ended, I never saw the io_service to stop.
So finally I let my async client to fill some global variable with the received data inside the handle_read and not to call directly another function like FireAnEvent. And I moved the call of this function (FireAnEvent) just after the io_service.run(). And it worked because after the end of the run() method I know that the loop is completely finished!
I hope my answer will help people :)
I have a List (e.g. the output of a database query) variable, which I use to create actors (they could be many and they are varied). I use the following code (in TestedActor preStart()), the actor qualified name is from the List variable as an example):
Class<?> classobject = Class.forName("com.java.anything.actor.MyActor"); //create class from name string
ActorRef actref = getContext().actorOf(Props.create(classobject), actorname); //creation
the code was tested:
#Test
public void testPreStart() throws Exception {
final Props props = Props.create(TestedActor.class);
final TestActorRef<TestedActor > ref = TestActorRef.create(system, props, "testA");
#SuppressWarnings("unused")
final TestedActor actor = ref.underlyingActor();
}
EDIT : it is working fine (contrary to the previous post, where I have seen a timeout error, it turned out as an unrelated alarm).
I have googled some posts related to this issue (e.g. suggesting the usage of newInstance), however I am still confused as these were superseded by mentioning it as a bad pattern. So, I am looking for a solution in java, which is also safe from the akka point of view (or the confirmation of the above pattern).
Maybe if you would write us why you need to create those actors this way it would help to find the solution.
Actually most people will tell you that using reflection is not the best idea. Sometimes it's the only option but you should avoid it.
Maybe this would be a solution for you:
Since actors are really cheap you can create all of them upfront. How many of them do you have?
Now the query could return you a path to the actor, not the class. Select it with actorSelection and send messages to it.
If your actors does a long running job you can use a router or if you want to a Proxy Actor that will spawn other actors as needed. Other option is to create futures from a single actor.
It really depends on the case, because you may need to create multiple execution context's not to starve any of the actors (of futures).
I have been using this code to display IMAP4 messages:
void DisplayMessageL( const TMsvId &aId )
{
// 1. construct the client MTM
TMsvEntry indexEntry;
TMsvId serviceId;
User::LeaveIfError( iMsvSession->GetEntry(aId, serviceId, indexEntry));
CBaseMtm* mtm = iClientReg->NewMtmL(indexEntry.iMtm);
CleanupStack::PushL(mtm);
// 2. construct the user interface MTM
CBaseMtmUi* uiMtm = iUiReg->NewMtmUiL(*mtm);
CleanupStack::PushL(uiMtm);
// 3. display the message
uiMtm->BaseMtm().SwitchCurrentEntryL(indexEntry.Id());
CMsvOperationWait* waiter=CMsvOperationWait::NewLC();
waiter->Start(); //we use synchronous waiter
CMsvOperation* op = uiMtm->OpenL(waiter->iStatus);
CleanupStack::PushL(op);
CActiveScheduler::Start();
// 4. cleanup for example even members
CleanupStack::PopAndDestroy(4); // op,waiter, mtm, uimtm
}
However, in case when user attempts to download a remote message (i.e. one of the emails previously not retrieved from the mail server), and then cancels the request, my code remains blocked, and it never receives information that the action was canceled.
My question is:
what is the workaround for the above, so the application is not stuck?
can anyone provide a working example for asynchronous call for opening remote messages which do not panic and crash the application?
Asynchronous calls for POP3, SMTP and local IMAP4 messages work perfectly, but remote IMAP4 messages create this issue.
I am testing these examples for S60 5th edition.
Thank you all in advance.
First of all, I would retry removing CMsvOperationWait and deal with the open request asynchronously - i.e. have an active object waiting for the CMsvOperation to complete.
CMsvOperationWait is nothing more than a convenience to make an asynch operation appear synchronous and my suspicion is that this is culprit - in the case of download->show message, there are two asynch operations chained.