2012-11-09 17:16:17 utc |
lmarburger |
the ruote documentation is fantastic! |
2012-11-09 21:47:28 utc |
jmettraux |
lmarburger: hello and welcome to #ruote, thanks for the compliment, first time I ever heard it :-) |
2012-11-09 21:58:19 utc |
lmarburger |
jmettraux: there's no way i'd believe i'm the first person to comment on the thoroughness of your documentation :) |
2012-11-09 22:05:27 utc |
jmettraux |
unfortunately, the documentation is lagging for some implementation points |
2012-11-09 22:07:37 utc |
lmarburger |
be that as it may, i just spent 2 hours reading pretty much everything i could find on http://ruote.rubyforge.org and there's still a lot i didn't get in to |
2012-11-09 22:08:40 utc |
lmarburger |
i have one question regarding persistence i was hoping you could answer |
2012-11-09 22:10:28 utc |
lmarburger |
let's say i have a participant that will send an email and wait some timeout duration to give the person a chance to respond. would that participant be a subclass of StorageParticipant? using ruote-sequel if that matters. |
2012-11-09 22:10:55 utc |
jmettraux |
ruote-sequel doesn't matter |
2012-11-09 22:11:03 utc |
jmettraux |
you could use timers |
2012-11-09 22:11:19 utc |
jmettraux |
give me one minute, I'm finishing an email |
2012-11-09 22:13:02 utc |
jmettraux |
email, done, it's actually showing a "missing documentation" point: https://groups.google.com/forum/?fromgroups=#!topic/openwferu-users/vV0sM3D_yYY |
2012-11-09 22:13:05 utc |
lmarburger |
no problem. the one thing i don't quite "get" yet is how workitems are persisted. i want to have a few concurrent workers that i can scale as needed. |
2012-11-09 22:13:33 utc |
lmarburger |
i figured that was the email you were replying to. i just joined the list. |
2012-11-09 22:14:52 utc |
jmettraux |
you can use a timer http://ruote.rubyforge.org/common_attributes.html#timers |
2012-11-09 22:15:45 utc |
jmettraux |
alice :timers => "5d: reminder, 10d timeout" |
2012-11-09 22:15:48 utc |
jmettraux |
for example |
2012-11-09 22:17:56 utc |
jmettraux |
each time you have a participant expression in a flow and the engine hands it a workitem |
2012-11-09 22:18:32 utc |
jmettraux |
the expression will at first be persisted in the storage (and that piece of data contains a copy of the workitem as applied) |
2012-11-09 22:19:16 utc |
jmettraux |
then the participant expression gets a fresh instance of the registered participant implementation and hands it the workitem |
2012-11-09 22:19:17 utc |
lmarburger |
oh ok. so if i have a participant that does some work in #on_workitem but doesn't #reply, will that be persisted for me? |
2012-11-09 22:19:36 utc |
jmettraux |
no |
2012-11-09 22:20:04 utc |
jmettraux |
in the participant implementation no |
2012-11-09 22:20:16 utc |
jmettraux |
in the participant expression there is a copy of the workitem as applied |
2012-11-09 22:20:27 utc |
jmettraux |
some participant implementation rely on that piece of info |
2012-11-09 22:20:50 utc |
jmettraux |
some participant implementationS |
2012-11-09 22:21:02 utc |
lmarburger |
ok that makes sense. |
2012-11-09 22:29:34 utc |
lmarburger |
going back again to sending emails. if i wanted to have a simple email chain of a few people where it would try each with a time out. i'd have some external process would need to pull a workitem out of storage and either resolve the process complete ("i'm taking care of this") or advance it to the next participant ("i'm busy") |
2012-11-09 22:29:55 utc |
lmarburger |
for some reason accomplishing that workflow isn't clicking for me |
2012-11-09 22:30:16 utc |
jmettraux |
for me neither |
2012-11-09 22:30:29 utc |
jmettraux |
ok, small bites |
2012-11-09 22:30:51 utc |
jmettraux |
having a external process querying some storage participant is OK |
2012-11-09 22:31:21 utc |
jmettraux |
list the workitems, find the ones for me |
2012-11-09 22:31:51 utc |
jmettraux |
update the workitem, set a "resolution" field with either "done" or "pass" |
2012-11-09 22:32:10 utc |
lmarburger |
yeah that's exactly it |
2012-11-09 22:32:18 utc |
jmettraux |
the rest of the flow can then use that resolution to decide |
2012-11-09 22:32:44 utc |
jmettraux |
the storage participant has a #proceed(workitem) method |
2012-11-09 22:33:11 utc |
jmettraux |
which does "hey mister engine, I'm done with the workitem, please let it resume in the flow" |
2012-11-09 22:34:10 utc |
jmettraux |
but I see more cases where the participant implementation hands the workitem to the external app over HTTP or AMQP or simply by spawning the external process |
2012-11-09 22:34:17 utc |
jmettraux |
many ways to skin a cat |
2012-11-09 22:35:37 utc |
lmarburger |
so if the participant were communicating with an external HTTP API, would it be a subclass of StorageParticipant and ping the API in #on_workitem? |
2012-11-09 22:35:51 utc |
jmettraux |
no |
2012-11-09 22:36:02 utc |
lmarburger |
ok good because that wasn't working for me :) |
2012-11-09 22:36:51 utc |
jmettraux |
people are obsessed with subclassing storage participant, although I can't remember having provided an example of such a participant |
2012-11-09 22:37:58 utc |
lmarburger |
i saw one here https://groups.google.com/d/msg/openwferu-users/LmqVcIwQhHs/bRableTLd40J |
2012-11-09 22:38:41 utc |
jmettraux |
that's for a side effect, not the main effect |
2012-11-09 22:39:19 utc |
jmettraux |
good catch anyway |
2012-11-09 22:39:59 utc |
jmettraux |
it could be implemented with a vanilla storage participant and an immediate reminder |
2012-11-09 22:40:00 utc |
lmarburger |
ah ok |
2012-11-09 22:40:34 utc |
jmettraux |
2010, at this point the :timers attribute wasn't that sophisticated |
2012-11-09 22:43:42 utc |
lmarburger |
ok so pardon my ignorance but what is "reminder" and "final_reminder" in this example: alice :timers => '5d: reminder, 12d: final_reminder, 15d: timeout' |
2012-11-09 22:44:07 utc |
lmarburger |
assuming "alice" is a StorageParticipant since i think that's what i need in my case |
2012-11-09 22:44:19 utc |
jmettraux |
no worries, in that mini language, "reminder" can either be a participant [name] or a subprocess [name] |
2012-11-09 22:44:25 utc |
lmarburger |
oh! |
2012-11-09 22:44:41 utc |
lmarburger |
wow ok |
2012-11-09 22:45:21 utc |
jmettraux |
ACTION now wonders if the info handed to reminder contains the alice participant name somehow |
2012-11-09 22:46:40 utc |
lmarburger |
so does this make sense: alert timers: '0m: sms, 5m: email, 1h: timeout' |
2012-11-09 22:46:54 utc |
lmarburger |
assuming "alert" is a StorageParticipant |
2012-11-09 22:47:01 utc |
jmettraux |
sounds right |
2012-11-09 22:47:37 utc |
lmarburger |
side question, does ruote_logger log this channel somewhere publicly? |
2012-11-09 22:47:46 utc |
jmettraux |
yes |
2012-11-09 22:48:03 utc |
jmettraux |
http://ruote-irclogs.s3.amazonaws.com/logs.html |
2012-11-09 22:49:13 utc |
lmarburger |
jmettraux: thanks for your help! |
2012-11-09 22:49:20 utc |
jmettraux |
you're welcome! |
2012-11-09 23:18:22 utc |
lmarburger |
jmettraux: while i have you on the line, what if i wanted to display a history of all the messages that were delivered. is that something that i could use ruote's StorageHistory for or would i be better off persisting those events myself? |
2012-11-09 23:42:59 utc |
jmettraux |
lmarburger: if by message you mean ruote inner messages then that's the job of the storage history, if you mean "workitem dispatched to participant implementation" then some filtering of the storage history log is necessary |
2012-11-09 23:43:23 utc |
jmettraux |
if you have more specialized need, then maybe your own piece of code could help |
2012-11-09 23:44:37 utc |
lmarburger |
ok i just made this up so i'm sure i got something wrong, but you'll probably be able to understand the outcome i'm trying to achieve |
2012-11-09 23:45:37 utc |
lmarburger |
jmettraux: let me know what you think of this: https://gist.github.com/afeeb7c1d91455790140 |
2012-11-09 23:46:24 utc |
lmarburger |
handle_alerts is a StorageParticipant, im, sms, email, and call are all participants i'd build that would just fire off calls to external APIs. |
2012-11-09 23:46:39 utc |
jmettraux |
sounds right |
2012-11-09 23:47:00 utc |
jmettraux |
looks right |
2012-11-09 23:48:00 utc |
jmettraux |
"0m: spam" maybe |
2012-11-09 23:48:36 utc |
lmarburger |
oh right |
2012-11-09 23:49:05 utc |
lmarburger |
ok so the next piece of the puzzle is i'd like other people (geeks/programmers) to write this process without having to understand the inner workings of ruote and my system |
2012-11-09 23:50:07 utc |
lmarburger |
maybe that's just a matter of taking the process they provide and appending some behavior |
2012-11-09 23:51:11 utc |
jmettraux |
well, you'd have to teach them ruote's language |
2012-11-09 23:51:25 utc |
jmettraux |
or write your own mini language and translate it to ruote |
2012-11-09 23:51:53 utc |
jmettraux |
and teach that mini language |
2012-11-09 23:52:02 utc |
lmarburger |
i was kicking around the idea of a mini language but thought it may be overkill |
2012-11-09 23:52:10 utc |
jmettraux |
I have to say your piece of code is quite readable |
2012-11-09 23:52:44 utc |
lmarburger |
it's the last line that i don't think will make sense to people who don't know how things work under the covers |
2012-11-09 23:53:40 utc |
lmarburger |
but maybe i just have people write a process that contains a known subprocess ("spam" in the gist) |
2012-11-09 23:54:05 utc |
lmarburger |
and then i can append the storage participant with timers to it without them knowing |
2012-11-10 00:00:21 utc |
jmettraux |
maybe something like https://gist.github.com/4049089 |
2012-11-10 00:00:52 utc |
jmettraux |
the notifications are immediate, no need to put them in a timers sequence |
2012-11-10 00:03:10 utc |
lmarburger |
oh awesome. i don't need the timers? |
2012-11-10 00:03:31 utc |
jmettraux |
ah well, sorry |
2012-11-10 00:03:36 utc |
jmettraux |
I made a mistake |
2012-11-10 00:03:38 utc |
lmarburger |
so it'd send the alerts and then store it? |
2012-11-10 00:03:59 utc |
jmettraux |
the timer is better because it hides the impliciment concurrence |
2012-11-10 00:04:06 utc |
lmarburger |
ok cool |
2012-11-10 00:08:08 utc |
jmettraux |
there is a participant-defined timers technique, https://github.com/jmettraux/ruote/blob/0c9841a1b2db5112fdf90ebed16c5eb08bd99e72/test/functional/ft_65_timers.rb#L250-275 |
2012-11-10 00:08:22 utc |
jmettraux |
but granted, it doesn't work with an out of the box participant |
2012-11-10 00:08:28 utc |
jmettraux |
out of the box storage participant |
2012-11-10 00:08:49 utc |
jmettraux |
but it hides the "timers" from the process definition |
2012-11-10 00:09:43 utc |
jmettraux |
I guess the easiest way is to have a "handle_alert" subprocess which hides the participant call + timers from the main definition |
2012-11-10 00:16:08 utc |
lmarburger |
jmettraux: oh right. i could define that handle_alert subprocess outside of the user-supplied script |
2012-11-10 00:16:18 utc |
jmettraux |
+1 |
2012-11-10 00:17:15 utc |
lmarburger |
this is making a lot of sense. i think the gist you and i pasted above gets me about 98% to where i want to be in terms of the dsl. i think i can get the rest of the way just by implementing this and understand how everything plays together |
2012-11-10 00:17:31 utc |
lmarburger |
whether it's #rtimers or externally defined subprocesses \ |
2012-11-10 00:19:27 utc |
jmettraux |
great |
2012-11-10 00:19:36 utc |
lmarburger |
thanks again for your help |
2012-11-10 00:19:51 utc |
jmettraux |
you're welcome |