In thinking about how to build web applications that scale, where
workitems get dispatched to people or groups, I found the stores
scheme to be a bit unwieldy.    My thinking is as follows:
- Work items can be dispatched to a person.
- Work items can be dispatched to a group.
- I should not need to iterate over the work items in a store or all
relevant stores
  looking at parameters in each work item to select workitems meant to
be acted
  on by a user or group.. that's what databases are good at.


I've made a few slight extensions to the ActiveWorkItem that may be of
interest to people that have similar needs.  The idea is that each
workitem, by convention has 'target' parameter.
e.g. consider a process for handling travel requests; where we have
defined the todo and approval stores to handle participants of the
form: todo.* and approval.* respectively.
A user creates a travel request.  It must be approved by the person's
manager and
the person who holds the budget on which the travel will be re-
imbursed (may or may not be the same person).  Then someone in our
travel group must fill in a form expected by our parent organization
(we are a laboratory at a university).

class Travel < OpenWFE::ProcessDefinition
    set :v => "linemanager", :value => "approval_linemanager"
    set :v => "budget",      :value => "approval_budgetsupervisor"
    set :v => "msuform",     :value => "todo.msutravelform"

    set :f => "recordid", :value => "#{$processInfo['recordid']}"
    set :f => "requestor", :value => "#{$processInfo['requestor']}"
    set :f => "type",     :value => "#{$processInfo['type']}"

    sequence do
        concurrence do

            linemanager :target     =>
"user:#{$processInfo['linemanager']}"
            budget            :target     =>
"user:#{$processInfo['budgetmanager']}"
        end

        msuform             :target     => "group:travel"
    end
end

and where $processInfo is setup by the application to be a hash that
parameterizes the process instance.   The modifications consist of
adding a key field to the ActiveRecordParticipant, target which is set
if the attribute['params']  hash has a key 'target'.  showing these
changes:

    class OwfeTables < ActiveRecord::Migration
        def self.up
            create_table :workitems do |t|
                t.column :fei, :string
                t.column :wfid, :string
                t.column :wf_name, :string
                t.column :wf_revision, :string
                t.column :participant_name, :string
                t.column :store_name, :string
                t.column :dispatch_time, :timestamp
                t.column :last_modified, :timestamp
                t.column :target,  :string                         #
<---- new field
            end
            add_index :workitems, :target, :unique => false   # <---
an index

Making the target field an index should make these searches scalable
with
performance O(log(n)) where n is the number of in flight workitems for
most
decent database engines.

and this field gets set a bit later in the file in:

        def Workitem.from_owfe_workitem (wi, store_name=nil)

            i = nil

            MUTEX.synchronize do

                i = Workitem.new
                i.fei = wi.fei.to_s
                i.wfid = wi.fei.wfid
                i.wf_name = wi.fei.workflow_definition_name
                i.wf_revision = wi.fei.workflow_definition_revision
                i.participant_name = wi.participant_name
                i.dispatch_time = wi.dispatch_time
                i.last_modified = nil

                i.store_name = store_name

                # If there is a target set that field as well...
<----- additions starts here.

                if wi.attributes['params']
                    parameter_hash = wi.attributes['params']
                    if parameter_hash['target']
                        i.target = parameter_hash['target']
                    end
                end
#    <----- additions end here.
...


Now I can do things like fill the dashboard for a user by
        @my_items =
Workitem.find_all_by_target("user:#{someusername}"}


     and I can iterate over the groups the user is a member of doing

       @my_items[thisgroup] =
Workitem.find_all_by_target("group:#{thisgroup}")


If it meets your needs, have fun with it... however  the usual
disclaimers of merchantability and fitness apply ;-).



Ron.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"OpenWFEru users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/openwferu-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to