ruote-kit – how to start?

36 views
Skip to first unread message

Christian

unread,
Jan 31, 2010, 5:07:48 PM1/31/10
to ruote
Hello all on the list!
I am trying to set up a tiny application with route-kit. Installation
was successful and I already loaded a small workflow in the browser
interface.
I was looking into the directory structure to find out how to start
developing some views and participants, but I'm completely lost. I
have little experiences with rails so far. Are views completly edited
by hand or is it possible to generate them via something like a
scaffolding? Where do I put my views in? How do I connect the engine
to get workitems?

kind regards,

Christian

Torsten Schoenebaum

unread,
Feb 1, 2010, 3:36:53 AM2/1/10
to openwfe...@googlegroups.com
Hi!

I fear I'll confuse you even more, but I'll try my best to shed some
light on the usage of ruote-kit (furthermore abbreviated as rk) and
Ruote in a Rails app.

Christian wrote:
> I was looking into the directory structure to find out how to start
> developing some views and participants, but I'm completely lost.

There's no need to change rk if you want to use it. rk is (something
like) a RESTful wrapper to Ruote itself. If you want to use the REST
interface rk provides, you could (and probably should) use the client
library ruote-kit-client (http://github.com/kennethkalmer/ruote-kit-client).

> I have little experiences with rails so far.

You don't have to use rk if you just need Ruote in your Rails app (and
btw, you don't even need Rails for rk nor Ruote -- rk is a Sinatra app).

You may:
1. use Ruote directly from your own (Rails|Sinatra|whatever) application
(with or without rk to peep into the running workflow processes)
2. use rk-client to access a running rk instance
3. put rk into your Rack app's middleware stack (see rk's Readme)

I'll use the first option here at my place, so Kenneth will have to
provide some more information on the other two, especially the third
one, which sounds pretty nice (less configuration needs on your side).
The second option would be most useful when your app and rk won't run on
the same server, I suppose.

> Are views completly edited by hand or is it possible to generate them
> via something like a scaffolding?

There's no scaffolding at the moment.

> Where do I put my views in?

What do you like to do with the 'views'?

You'll have to start a new (Rails|Sinatra|whatever) application if you
want to use Ruote or rk. Ruote and rk won't bother where you're views
are ;-)

OK, let's assume you choose the first option mentioned above (sorry,
this is not the answer to your original question, but I hope it helps
anyway) and you plan to write a shiny new Rails app. You could re-use my
configuration example here:

http://gist.github.com/286669

Then, you could use

Ruote.engine

anywhere in your app to access the Ruote engine instance.

Ruote.storage_participant

would be the shortcut to the storage participant registered for
workflow_step_.*.

So let's have an example controller action which simply fetches all
workitems from the storage participant:
class WorklistController < ActionController::Base
def index
@workitems = Ruote.storage_participant.all
end
end

and the corresponding view (app/views/worklist/index.html.haml):
.workitems
- @workitems.each do |wi|
%div[wi]
&= wi.fields['foo']

Note that you'll have to run a Ruote worker by calling

$ rake ruote:run_worker

if you don't want your processes to be stalled.

The mentioned gist includes an example for a custom participant
implementation.


For using rk-client see its Readme, it should be enough to get going.
The controller action could then be rewritten to:
def index
client = RuoteKit::Client(RUOTE_KIT_URL)
@workitems = client.workitems
end

Hope this helps, fire away with further questions,
Torsten

Dave @ UPENN

unread,
Feb 2, 2010, 4:49:13 PM2/2/10
to ruote
Thanks for this! I'm having a little using the new ruote with rails
and this was a big help. I'll probably have a few questions for you in
the near future...

On Feb 1, 3:36 am, Torsten Schoenebaum <torsten.schoeneb...@web.de>
wrote:

Torsten Schoenebaum

unread,
Feb 9, 2010, 10:02:20 AM2/9/10
to openwfe...@googlegroups.com
Hi list!

A little follow up to my lines on using Ruote from within Rails. I
mentionend "put rk into your Rack app's middleware stack" as possibility
for that without giving further details.

Kenneth did some fine work on that and I added a few more lines so that
now I would propagate to use RuoteKit when there's a need for Ruote on
Rails.

If you need a quickstart, have a look at my example Rails app at
http://github.com/tosch/ruote-on-rails

The only files changed are:
* config/environment.rb
* config/initializers/ruote_kit.rb
* lib/tasks/ruote_kit.rake

You get all the power of the changes done in my previously mentioned
gist plus the possibility to peep into running processes by surfing to
/_ruote.

There's just one drawback at the moment: RuoteKit's views and methods
aren't protected in any way, they are accessible to the world if you
don't protect them by yourself in some way.


So let's dig a little deeper: Where to put your own Ruote stuff?

First of all, you should register your participants in the ruote_kit.rb
initializer file (before the RuoteKit.configure_catchall! call). Note
that you should only use non-instanciated participants as the Ruote
engine when running Rails has no access to a worker instance by default
(instanciated participants will only work if a worker is bound to the
engine). That means: Don't use BlockParticipants! Don't use
ParticipantClass.new. Those will most probably not work.

Some words on the catchall participant: The call to
RuoteKit.configure_catchall!
is a shortcut for the following:
RuoteKit.engine.register_participant('.*', Ruote::StorageParticipant)
So you'll get a storage participant for every participant name you may
think of. If you didn't register your own participants beforehand, every
time a participant expression is entered in your processes, a workitem
will be put in the storage participant. You may access all storaged
workitems by calling RuoteKit.storage_participant.all. See
Ruote::StorageParticipant's inline docu for all methods you may or may
not need ;-)

Note that there is no need to run RuoteKit.configure_catchall! ! The
storage participant will be there anyway, but you'll have to register it
by yourself if you want to use it in your process definitions. You could
register a not so greedy (name-wise) variant:
RuoteKit.engine.register_participant 'storage_+*', Ruote::StorageParticipant
In your process definitions, each participant expression refering to
storage_a or storage_b etc would be handled by the storage participant.

Apropos process definitions: Where to put them? You may keep it simple
and put them in the initializer (writing to some global constant for
example). John likes them to be referenced by urls, so you could put
them as files in some subdirectory of public [1]. You can even put the
process definition to the place where you launch processes. In short
words: It's totally up to you.

Now you have your participants registered and your process definitions
(f)lying around somewhere. Where to launch them? The possibilities are
nearly endless. You could call RuoteKit.engine.launch in your
controllers. I would suggest to use one or more methods in your models
for that, combined with callbacks and/or observers. The best way depends
on your models, so YMMV.

For human participant integration, the storage participant is built. It
holds the workitems until they are explicitely replied to the engine
(you can do this via
RuoteKit.storage_participant.reply(workitem)
). There could be a controller wrapping all this up, but for a start,
there always is /_ruote/workitems ...

That's all for now. I hope this helps and am waiting for questions,
Torsten

[1] Note that you have to set the remote_definition_allowed option of
the engine to true to get that going.

Dave @ UPENN

unread,
Feb 19, 2010, 1:11:31 PM2/19/10
to ruote
Hey Torsten,

I was able to get your initial setup working fine, but then i tried to
install the ruotekit modifications into my other existing rails app
and now i keep getting this sinatra error:

=> Booting Mongrel
=> Rails 2.3.4 application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
Fri Feb 19 13:06:04 -0500 2010: Read error: #<MissingSourceFile: no
such file to load -- sinatra/respond_to>
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
`gem_original_require'
/opt/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
`require'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/
active_support/dependencies.rb:156:in `require'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/
active_support/dependencies.rb:521:in `new_constants_in'

...

any ideas?

Thanks,
Dave

BTW ruote-on-rails works fine with your initial set of instructions.

On Feb 9, 10:02 am, Torsten Schoenebaum <torsten.schoeneb...@web.de>
wrote:


> Hi list!
>
> A little follow up to my lines on using Ruote from within Rails. I
> mentionend "put rk into your Rack app's middleware stack" as possibility
> for that without giving further details.
>
> Kenneth did some fine work on that and I added a few more lines so that
> now I would propagate to use RuoteKit when there's a need for Ruote on
> Rails.
>

> If you need a quickstart, have a look at my example Rails app athttp://github.com/tosch/ruote-on-rails

Dave @ UPENN

unread,
Feb 19, 2010, 1:22:21 PM2/19/10
to ruote
hmm i sudo gem installed sinatra-respond_to and it seems to be working
now. i think there's something wrong with my gem repo or something.
anyways, this works great thanks!

On Feb 19, 1:11 pm, "Dave @ UPENN" <davejun...@gmail.com> wrote:
> Hey Torsten,
>
> I was able to get your initial setup working fine, but then i tried to
> install the ruotekit modifications into my other existing rails app
> and now i keep getting this sinatra error:
>
> => Booting Mongrel

> => Rails 2.3.4 application starting onhttp://0.0.0.0:3000

Christian

unread,
Mar 9, 2010, 6:04:21 PM3/9/10
to ruote
Hi Thorsten, Thank you for your detailed description, it helps a lot!

I am trying now your old configuration and the new ruote-on-rails in
parallel. But i have still some issues.
I already instaled the ruote-kit gem with sudo gem install ruote-kit.
When I try to do some scaffolding I always get the following errors:

/opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/rails/
gem_dependency.rb:119:Warning: Gem::Dependency#version_requirements is
deprecated and will be removed on or after August 2010. Use
#requirement
/ruote-on-rails/config/initializers/ruote_kit.rb:14: undefined method
`configure_catchall!' for RuoteKit:Module (NoMethodError)
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/activesupport-2.3.5/
lib/active_support/dependencies.rb:145:in
`load_without_new_constant_marking'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/activesupport-2.3.5/
lib/active_support/dependencies.rb:145:in `load'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/activesupport-2.3.5/
lib/active_support/dependencies.rb:521:in `new_constants_in'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/activesupport-2.3.5/
lib/active_support/dependencies.rb:145:in `load'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:622:in `load_application_initializers'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:621:in `each'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:621:in `load_application_initializers'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:176:in `process'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:113:in `send'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
initializer.rb:113:in `run'
from /ruote-on-rails/config/environment.rb:9
from /opt/ruby-enterprise/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:31:in `gem_original_require'
from /opt/ruby-enterprise/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:31:in `require'
from /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/
commands/generate.rb:1
from /opt/ruby-enterprise/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:31:in `gem_original_require'
from /opt/ruby-enterprise/lib/ruby/site_ruby/1.8/rubygems/
custom_require.rb:31:in `require'
from script/generate:3

I am using ruby enterprise edition on ubuntu 9.10.

I also have some question about the StorageParticipant. Am I right
with the assumption, that all the workitem manipulation should be done
"outside" any ruote participant?
When is the workitem created?
I did some initialization (engine.launch) and get the workitems out of
the participant with storageParticipant.all. They all seem to be
vompletely empty. Shouldn't they have at least a fei or something
alike stored in it?

I hope my questions are not to stupid.

regards,

Christian

John Mettraux

unread,
Mar 9, 2010, 7:08:59 PM3/9/10
to openwfe...@googlegroups.com
On Wed, Mar 10, 2010 at 8:04 AM, Christian <rde...@googlemail.com> wrote:
> Hi Thorsten, Thank you for your detailed description, it helps a lot!

Hello Christian,

next time could you please start a new thread ? Thanks in advance. If
you really need to link to a previous conversation, use a link like :

http://groups.google.com/group/openwferu-users/t/2c012627bdb5b1e7

> I am trying now your old configuration and the new ruote-on-rails in
> parallel. But i have still some issues.
> I already instaled the ruote-kit gem with sudo gem install ruote-kit.
>
> When I try to do some scaffolding I always get the following errors:
>

> (...)


>
> /ruote-on-rails/config/initializers/ruote_kit.rb:14: undefined method
> `configure_catchall!' for RuoteKit:Module (NoMethodError)

Strange, what does your ruote_kit.rb look like ? No changes from

http://github.com/tosch/ruote-on-rails/blob/master/config/initializers/ruote_kit.rb

?

> (...)


>
> I am using ruby enterprise edition on ubuntu 9.10.


> I also have some question about the StorageParticipant. Am I right
> with the assumption, that all the workitem manipulation should be done
> "outside" any ruote participant?

Please define "ruote participant", please define "outside". Well,
could you please rephrase your question ?

> When is the workitem created?

When a process instance is launched, a workitem is created inside of
the engine and travels throughout the instance. When a concurrence is
reached, the workitem gets cloned, when the concurrence is over, the
workitem gets re-united.

When a workitem reaches a participant expression (something like
'participant :ref => "toto"') the engine will dispatch the workitem
(at least a copy of it) to the "real participant". Usually that
implies calling the "consume" method of a participant implementation.

In the case of StorageParticipant, the workitem will appear in the
list of workitems of the participant and you can "update" it or
directly "reply" with it. (update and reply are two instance methods
of StorageParticipant).

> I did some initialization (engine.launch) and get the workitems out of
> the participant with storageParticipant.all. They all seem to be
> vompletely empty. Shouldn't they have at least a fei or something
> alike stored in it?

There should be a fei :

---8<---
p workitem.fei
p workitem.fields
p workitem.participant_name
--->8---

You can set initial fields for the workitem when launching :

---8<---
RuoteKit.engine.launch(
process_definition,
'project' => 'new pasta machine',
'budget_range' => 'low',
'customer_classes' => [ 'small businesses', 'medium businesses' ])
--->8---

The initial workitem in your newly launched process instance will have
those 3 'project', 'budget_range' and 'customer_classes' fields.

It's also OK to set fields later in the process :

http://ruote.rubyforge.org/exp/set.html
http://ruote.rubyforge.org/exp/restore.html (see "set_fields")


> I hope my questions are not to stupid.

Not at all :) I hope the current answers are helpful.


Best regards,

--
John Mettraux - http://jmettraux.wordpress.com

Torsten Schoenebaum

unread,
Mar 10, 2010, 2:19:43 AM3/10/10
to openwfe...@googlegroups.com
Christian schrieb:
> Hi Thorsten
^ the 'h' is yours, not mine ;-)

> I am trying now your old configuration and the new ruote-on-rails in
> parallel.

That means in two parallel Rails instances or in one? I wouldn't
recommend the latter...

> But i have still some issues.
> I already instaled the ruote-kit gem with sudo gem install ruote-kit.

Does it appear in the list when you do a
$ gem list
?

> When I try to do some scaffolding I always get the following errors:
>
> /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/rails/
> gem_dependency.rb:119:Warning: Gem::Dependency#version_requirements is
> deprecated and will be removed on or after August 2010. Use
> #requirement
> /ruote-on-rails/config/initializers/ruote_kit.rb:14: undefined method
> `configure_catchall!' for RuoteKit:Module (NoMethodError)

It seems the ruote-kit gem isn't loaded properly. Do you have access to
other methods the module provides (you could try that in the console)?
How does your environment.rb look like?

Where did you get the gem from? Did you build it yourself or is it the
one from gemcutter.org?

> I am using ruby enterprise edition on ubuntu 9.10.

So do I without having troubles.

Note that the configure_catchall! method will vanish most probably in
one of the next rk versions. Instead, there will be a register method in
the configuration. I will update ruote-on-rails to reflect this change.

Yours,
Tor"there are no stupid questions, but stupid answers"sten

Christian

unread,
Mar 10, 2010, 1:54:45 PM3/10/10
to ruote
John, Torsten, thanks for your quick reply!
I will answer to both of you in this mail.

First of all, my problem seemed to be that I had the wrong version of
ruote-kit (2.1.4.1) installed. As I looked into the code I realized,
that there was acually no configure_catchall! Now I have built the gem
myself with the sources from github.
Everything seems to run fine now!

concerning the workitems:
Indeed the workitems I have are not empty. I got it now running fine
(classical PEBKAC :-)

> Well, could you please rephrase your question ?

As Torsten wrote, one should use the storage participant (SP), if
human interaction is present. Thus, I want to use 3 SPs in sequence.
Since the SP cannot have any logic in it, I have to put it into e.g. a
controller where I pull the workitem from the SP and after processing
it, pass it back to the SP. Is this the right way to deal with the
SP?

> That means in two parallel Rails instances or in one?

They were running in parallel instances. Since their engine seems to
have the same ID, I now have all the workitems available in both
instances. Hence, I will discard the "old" Version and run route-on-
rails.

John, thanks for your brief explanation on workitems etc.
Torsten, thank you for your hint about where I got the gem from. That
drove me to the solution. I will also take the 'h' back and use it for
something else. :)
Best regards,

Christian

John Mettraux

unread,
Mar 10, 2010, 6:35:39 PM3/10/10
to openwfe...@googlegroups.com
On Thu, Mar 11, 2010 at 3:54 AM, Christian <rde...@googlemail.com> wrote:
>
>> Well, could you please rephrase your question ?
>
> As Torsten wrote, one should use the storage participant (SP), if
> human interaction is present. Thus, I want to use 3 SPs in sequence.
> Since the SP cannot have any logic in it, I have to put it into e.g. a
> controller where I pull the workitem from the SP and after processing
> it, pass it back to the SP. Is this the right way to deal with the
> SP?

Hello Christian,

yes, it's fine.

Here is something straight out of a ruote[-kit] + rails app I have :

---8<---
def update # a workitem

workitem = get_workitem

fields = Rufus::Json.decode(params[:workitem]['fields'])
workitem.fields.merge!(fields)

if params[:commit] == 'save'
#
# save

RuoteKit.storage_participant.update(workitem)

redirect_to :action => :show

else # if params[:commit] == 'forward'
#
# forward (workitem resume in flow)

RuoteKit.storage_participant.reply(workitem)

redirect_to :action => :index
end
end

protected

def get_workitem

fei = params[:id]

fei = Ruote::FlowExpressionId.from_id(fei.split('!')[-3..-1].join('!'))
# ruote 2.1.8 will fix that, making that line unnecessary

RuoteKit.storage_participant[fei]
end
--->8---

Workitem is retrieved in storage participant. New field values are
merged in, the if the "action" is 'forward', then the #reply method of
the participant is called, else simply the #update method (which will
save the workitem with its new fields).

Reply all
Reply to author
Forward
0 new messages