# Engines Collaboration \[was: DRY and engines\]

**URL:** <https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384>\
**Category:** Engines\
**Created:** [March 1, 2006, 8:39pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384 "2006-03-01T20:39:19Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 1, 2006, 8:39pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/1 "2006-03-01T20:39:19Z")

</div>

Here I accept James’ invitation to commence the discussion 🙂

Be aware: I enter pure brain storming mode 😉  
brain\_storming\_mode: ON

It looks like we want to achieve a greater level of DRYness while  
keeping the benefits of low configuration rate.

As most part of Rails code shows, we can try to do that by applying  
other important principles in a rigorous way:

- use convention, not configuration
- use composition, not inheritance

how to translate this in our case?

Well, here I guess we do need to add functionalities to the engines  
plugin.  
(I guess, and not know as a fact, because I haven’t yet studied the  
plugin code, if not locally).

What we need is a sort of “communication bus” between engines that  
enables inter engine communication.

The engines plugin could keep, for instace, a Register of the started  
engines together with their skills and then spread this knowledge in the  
registred engines community.

It could work like the following:

- the engines, when started, tell to the Register which service(s) they  
are offering (probably just a :symbol with the service name)

- when an engine needs a specific service, asks the Register a “pointer”  
to whoever provides it and then uses it.

- by using a solid interface naming convention, we could enable the  
possibility for the engines to load dinamically other engines behaviours  
if, and only if, they are available.

To esemplify:

- NeedyEngine needs somebody performing the do\_hard\_work service for  
him.

- the Register looks up in itself and finds that the ExpertEngine has  
registred offering the do\_hard\_work service.

- the Register returns to NeedyEngine a pointer to the ExpertEngine

- NeedyEngine “calls”  
ExpertEngine#do\_hard\_work({params}, :return\_to =\> “a/next/action” )

- The controll goes to ExpertEngine that can interact with the browser,  
do all his work and then return to NeedyEngine#a/next/action

- [optional] NeedyEngine provides internally (not registered) a  
do\_hard\_work dummy service implementing the Null pattern on itself.

Basically here we can use rules/conventions like:

- rule: the “:return\_to” parameter is mandatory  
or  
convention: if “:return\_to” is not given, then is assumed :index

- We could even estabilish an authority ([rails-engine.org](http://rails-engine.org) ?) that keeps  
a list of standardized services. This is a very important point to  
discuss!

Imagine that you are writing an Engine and you need it to use  
“authentication”.  
You look on-line at [rails-engine.org/services](http://rails-engine.org/services) and see that there is a  
definition for a standardized service named “authentication”.

Since the authority defines the standard parameters (like “:return\_to”)  
all the services are supposed to accept and keeps track of the service  
specific parameters as well (i.e. :password, :user for the  
“authentication” service), you can “use” the “authentication” service in  
your new Engine code, assuming that somebody wil provide an  
implementation for it (but don’t forget to write your dummy/default  
“authentication” service!!!).

Whoever wants can write an engine that offers the “autentication”  
service,  
and as long as it is engines-authority-standard compliant, it will be  
usable by your engine without any effort.

In other words: a huge Strategy pattern!!! (so we use “dynamic  
composition” instead of inheritance or, even worse, copy & paste).

brain\_storming\_mode: OFF

Waiting for opinions,

Mauro

James A. wrote:

> Both the User and Login engines could do with serious refactoring with  
> a view to making them much cleaner in terms of overriding behaviour. A  
> big part of this is probably going to be establishing a clear API for  
> both. Let the discussion commence!
> 
> - james
> 
> On 2/28/06, Bart M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > ```
> > session['return-to'] = '/books/create'
> > 
> > ```
> > 
> > course copy the complete new action, but this goes against the DRY  
> > user\_controller just to change \>one string. I’m not sure I can think of  
> > integrate it all together, by integrating the new user partial into the  
> > Bart

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 4, 2006, 3:16pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/2 "2006-03-04T15:16:51Z")

</div>

Hi Mauro,

That’s quite a system you describe - I’m not 100% clear on many of the  
aspects to be honest, but what I can tell you for certain is that it’s  
unlikely that I’ll have time to implement it in the near future! It  
also seems like quite a leap from the meagre functionality that the  
engines plugin provides at the moment.

For the moment, my personal work on engines is focussed on enabling  
the features that we need in my company, but that’s not to stop  
someone else extending it - this is the nature of open source of  
course.

It might be worth you writing another article where you can explore  
these ideas, and then when they are more fully-formed it will be  
clearer how the ‘engines philosophy’ might relate to your ideas of  
registries, specifications services.

- james

On 3/1/06, mauro cicio [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> What we need is a sort of “communication bus” between engines that
> 
> - when an engine needs a specific service, asks the Register a “pointer”
> 
> discuss!  
> your new Engine code, assuming that somebody wil provide an
> 
> > big part of this is probably going to be establishing a clear API for
> 
> –  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> * * *
> 
> engine-users mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.rails-engines.org/listinfo.cgi/engine-users-rails-engines.org](http://lists.rails-engines.org/listinfo.cgi/engine-users-rails-engines.org)

–

- J \*  
~

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 4, 2006, 4:30pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/3 "2006-03-04T16:30:45Z")

</div>

Hi James,

Thanks for your answer. My intent with the “Engines Collaboration”  
was to continue and stimulate the discussion on “DRY and engines”,  
more than specify how to achieve inter-engine communication  
at this moment.

You are right: what I suggest is not a minor change.

I think I follow up your suggestion: define the idea in  
greater detail and even prototype it.

I would like to have people’s input about it: does anybody  
feel that it could be worth to implement an inter-engine communication?  
Ideas?

Mauro

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 4, 2006, 7:52pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/4 "2006-03-04T19:52:02Z")

</div>

On 3/4/06, mauro cicio [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I think I follow up your suggestion: define the idea in  
> greater detail and even prototype it.
> 
> I would like to have people’s input about it: does anybody  
> feel that it could be worth to implement an inter-engine communication?  
> Ideas?
> 
> Mauro

By “inter-engine communication” are you talking about something like  
Java’s generic RMI interface that can span tiers, or something more  
specific to engines with well known services that is only used for  
intra-machine traffic?

I support a Java App that has several places where we do RMI.  
(Counting clients we have Java running on 5 different tiers of  
machines. We use RMI on several of the tier to tier connections.)

I’m still a newbie with Rails but it seems like any serious enterprise  
app will need to have an RMI like mechanism for the various tiers to  
talk together.

## Greg

Greg F.  
The Norcross Group  
Forensics for the 21st Century

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 4, 2006, 11:33pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/5 "2006-03-04T23:33:24Z")

</div>

> I would like to have people’s input about it: does anybody  
> feel that it could be worth to implement an inter-engine communication?  
> Ideas?

I’d rather see a standardized interface where an engine can access  
authentication or authorization information.

Can you give a concrete example of what you’re thinking of with  
inter-engines  
communication?

David

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 5, 2006, 1:38am UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/6 "2006-03-05T01:38:08Z")

</div>

Hi, Mauro.

> I would like to have people’s input about it: does anybody  
> feel that it could be worth to implement an inter-engine  
> communication?  
> Ideas?

Though I do not agree completely with DHH’s opinion about high level  
components, I think the project you described goes beyond the nice-  
and-easy things that Engines currently are and into the area of  
complex-hard-to-manage-and-Java-like things. Thus, the advantage of  
reuseability might come at a cost of too high complexity.

I will certainly not try to stop you from doing it but in my opinion  
the mixin and override features of Ruby could do many things such a  
layer would do: Define some callback methods like ActiveRecord’s  
callbacks and let users overwrite them in their current code.

If you want to pursue your ideas further, you might want to look at  
existing dependency injection and inversion of control libraries as  
Needle [1]. It offers an interface for registering services.

While these systems can reduce the complexity of huge systems you  
have to get over an “entry complexity barrier” - lest you invest more  
time planning and implementing the required overhead such systems  
bring than you save compared with rewriting.

I’ll be interested to read more about your ideas, though.

Regards,

Manuel H.

[1] [http://rubyforge.org/projects/needle](http://rubyforge.org/projects/needle)

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 5, 2006, 12:20am UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/7 "2006-03-05T00:20:57Z")

</div>

On Sat, 4 Mar 2006 16:30:45 +0100, mauro cicio wrote:

> I would like to have people’s input about it: does anybody  
> feel that it could be worth to implement an inter-engine communication?  
> Ideas?

I think that the proposal may be overly complex and genericized…  
defining  
a communications bus, service locator, etc. seems to be the opposite of  
“convention over configuration”.

Better would be things like Bill K.'s recent post on defining a common  
DSL for authentication. The service registry becomes Usenet and the  
Rails  
wiki. The protocol becomes “authors talk to each other”. The pointer  
is  
Google, and the naming convention is decided by the authors for any  
given  
service…

But then I can’t really think of a whole lot of situations OTHER than  
authentication, version control, wiki, and maybe blogging where you’ll  
likely have multiple engines implementing a common API but different  
underlying schemes.

Jay

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 5, 2006, 8:37am UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/8 "2006-03-05T08:37:59Z")

</div>

I completely agree.

Even more so to the idea, is to have a engine which is a hub for choice.  
Allowing you to configure which authentication schema you would like to  
use.

Whether its ActiveRBAC, acts\_as\_authenticated, acl\_system, user\_engine,  
or  
login\_engine, depending on whether you want just authentication, or ACL  
as  
well.

The Authentication Engine would serve as a communication mechanism  
between  
all the different plugins out there, providing a single, cohesive API  
which  
is standard no matter which authentication system you use. Even if you  
have  
you own home-brew authentication system, you could write a hook into the  
authentication\_engine.

I just created the ferret\_engine, which will be released soon, that  
another  
engine I have created, the toolbawks\_engine, interfaces with. I have  
created  
them quite tightly integrated, based on a configuration option in the  
toolbawks\_engine, that turns on/off the ferret\_engine functionality.

One of the ideas that James and I have been discussing, is an API for  
each  
of the engines, allowing each engine to communicate with another Engine.  
This API, in my opinion, would be absolutely best served with a local  
Web  
Service gateway. Which would provide the obvious later growth into  
having it  
as a public web service, allowing things such as the ferret\_engine be  
able  
to be searched on by remote or even local disseparate applications. This  
is  
definitely the way I want to go as far as engines API are concerned. It  
provides extreme flexibility when it comes to communication of  
functionality.

For instance, if we create the Engine API using a standardized web  
service  
architecture, future systems such as the authentication\_engine would be  
able  
to communicate with other Engines, such as the upcoming Toolbawks  
Engine, or  
Ferret Engine (to make sure they have access to search that content)  
with a  
very simplistic manner. I haven’t yet got much experience building Web  
Services, but I know enough high-level that this is the way to go, we  
just  
need to make it happen.

-Nb

```auto
 Nathaniel S. H. Brown http://nshb.net

```

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 5, 2006, 11:41am UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/9 "2006-03-05T11:41:06Z")

</div>

Hi everybody and thanks a lot for the input.

Tu sum up: it looks like there is enough interest on the topic  
to justify further investigation.

In the meanwhile I comment the several posts to try to find a common  
ground.

- Greg F.  
==========================================

> By “inter-engine communication” are you talking about something like  
> Java’s generic RMI interface that can span tiers, or something more  
> specific to engines with well known services that is only used for  
> intra-machine traffic?

I meant to talk about “something more specific to engines”.  
It would be interesting to work on something that can generalize the  
idea.

…

> I’m still a newbie with Rails but it seems like any serious enterprise  
> app will need to have an RMI like mechanism for the various tiers to  
> talk together.

I agree. In my view the excellent Rails was born as a WebFramework, not  
as an Enterprise Application Server, but has all the potential to become  
one.

- David C.  
==========================================

> I’d rather see a standardized interface where an engine can access  
> authentication or authorization information.

If you drop the “rather”, I fully agree 😉  
In fact my proposal is  
1 - have a central entity to help discovering the needed service.  
2 - to use the discovered service relying on standardized interface

and what you say is the second part of it.

> Can you give a concrete example of what you’re thinking  
> of with inter-engines communication?

Actually I could write a prototype, but before I want to collect ideas.  
For the moment I send the following standard, very simplified,  
“hub” code, just to avoid misunderstanding:

– Client Engine  
…  
login = Engines.find\_service(:login) # looks for a provider  
…  
login.validate(user, passwd) # uses standardized interface  
… # for that kind of provider

– Engines (framework side)  
…  
@services = {}

def Engines.start(engines) # (could be in the engines plugin)  
engines.eaach{|engine| @services[engine.offered\_service] = engines}  
…  
end

def Engines.find\_service(desired\_service); @services[desired\_service]  
end  
…

– Service Provider Engine  
…  
def offered\_service; :login end # hub code  
…

- Jay L.  
==========================================

> I think that the proposal may be overly complex and genericized…  
> defining  
> a communications bus, service locator, etc. seems to be the opposite of  
> “convention over configuration”.

Not really.  
1 - we are in Ruby: the expression “communications bus” is longer  
than its implementation 😉  
2 - the complexity, if any, is on the framework side, not on the  
Engine Client/Provider

> Better would be things like Bill K.'s recent post on defining a common  
> DSL for authentication.  
> The service registry becomes Usenet and the Rails wiki.  
> The protocol becomes “authors talk to each other”.  
> The pointer is Google, and the naming convention is decided by  
> the authors for any given service…

I am not familiar with Bill K.'s work, I’ll check it out.  
From what you say it looks like something quite different from what I  
suggest.  
Having a registry on the net creates strong dependencies (no net, no  
test)  
“authors talk to each other” is always good, but far from maintainable.

> But then I can’t really think of a whole lot of situations OTHER than  
> authentication, version control, wiki, and maybe blogging where you’ll  
> likely have multiple engines implementing a common API but different  
> underlying schemes.

Actually the whole topic started from your statement:

> > Another thing to think about: You want the engine to be easily  
> > extensible without folks having to modify the actual engine files, or  
> > cut-and-paste huge swaths of code.

Right!!!  
Getting a pointer to the service you want to use (by name) and acquire  
its  
behaviours dynamically (dyn composition), is a way to address this.  
The possibility to select between different implementation comes,  
basically, as a free of charge side effect.

- Manuel H.  
=============================================

> Though I do not agree completely with DHH’s opinion about high level  
> components,  
> I keep hearing about it, but never read it. Could you give me a pointer?

> I think the project you described goes beyond the nice-  
> and-easy things that Engines currently are and into the area of  
> complex-hard-to-manage-and-Java-like things. Thus, the advantage of  
> reuseability might come at a cost of too high complexity.

I agree with you: this has to be avoided at all costs!  
A lot of people in the Rails world are refugees from  
“complex-hard-to-manage-and-Java-like things” 😉

There is a distinction to do though: is the complexity on the  
framework or on its the users side?

Example: the fact that I need to type 15 time as much code to read a  
file  
in Java rather than in Ruby, doesn’t mean that the Ruby interpreter  
is simpler than the JVM. It means that it does more for me.

> I will certainly not try to stop you from doing it but in my opinion  
> the mixin and override features of Ruby could do many things such a  
> layer would do: Define some callback methods like ActiveRecord’s  
> callbacks and let users overwrite them in their current code.

Right. This could work and it is one of the topic I would like  
to discuss in higher detail. In the article  
[http://cicio.org/articles/engines\_isolation](http://cicio.org/articles/engines_isolation)  
I already tried to point out that in the engine community is  
understimating the conflict risks (poor namespace usage).  
The approach you suggest could be OK if applied in a consistent way.

> If you want to pursue your ideas further, you might want to look at  
> existing dependency injection and inversion of control libraries as  
> Needle [1]. It offers an interface for registering services.

I come from Spring, so this is a welcome hint. Thanks!

> While these systems can reduce the complexity of huge systems you  
> have to get over an “entry complexity barrier” - lest you invest more  
> time planning and implementing the required overhead such systems  
> bring than you save compared with rewriting.

You are right. My aim is to use the space for improvement that  
we have _without loss of simplicity_. If there is not such a space,  
I rather drop the topic.

> I’ll be interested to read more about your ideas, though.

And so do I about yours. You touched points I feel as very sensitive.

- Nathaniel B.  
===============================================  
No too much to say here. I just fully agree 🙂

- Mauro

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 5, 2006, 6:30pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/10 "2006-03-05T18:30:56Z")

</div>

After having read a few articles on Web service architecture, you are  
indeed  
right, it does add a layer of complexity. With that complexity comes  
significant advantages, such as the UDDI layer. Whereby, in such  
instance as  
we are discussing with the Engines, we would have a centralized  
uddi\_engine  
that would serve as the hub for the discovery of the local web service  
engines and provide the communication layer between each of the Engines.

For light reading I recommend checking out:

[http://www.w3.org/DesignIssues/WebServices.html](http://www.w3.org/DesignIssues/WebServices.html)

Don’t get me wrong, I am not one to choose a more difficult path without  
understanding the risks involved in doing so. And with something as  
important as what we are trying to do, whereby having a common thread by  
which inter-dependant Engines can communicate with each other, and even  
remote applications, is a very noble goal.

It will be a tougher path to take, which I can see why you my be adverse  
to  
following. Consider this though. Either we iron out the issues with  
local  
Engines that communicate with each other using Ruby alone, or we look at  
ironing out Engines communicating over a local Web Service  
infrastructure,  
there will be problems and complications, but when each are both done.  
Which  
will allow is a more flexible approach to growth in the future? Without  
a  
doubt, it would be the Web Service architecture.

The one and only primary concern I have with utilizing a 100% Web  
Service  
architecture is speed. This is something that will need to be seriously  
considered, but having this as the only road block in my mind is really  
quite trivial. And something we can optimize when the time presents  
itself.  
To quote Tony Hoare, “We should forget about small efficiencies, say  
about  
97% of the time: premature optimization is the root of all evil.”.

-Nb

```auto
 Nathaniel S. H. Brown http://nshb.net

```

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 5, 2006, 8:54pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/11 "2006-03-05T20:54:41Z")

</div>

Maybe I’m very wrong, but engines are not services. They are more than  
that,  
because services don’t generally have a UI.

If you want to go create “J2EE for Ruby” (which is what it kind of  
sounds like  
have at it, but don’t muck up engines in the process.

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 5, 2006, 12:42pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/12 "2006-03-05T12:42:19Z")

</div>

> For instance, if we create the Engine API using a standardized web service  
> architecture, future systems such as the authentication\_engine would be  
> able to communicate with other Engines, such as the upcoming Toolbawks  
> Engine, or Ferret Engine (to make sure they have access to search that  
> content) with a very simplistic manner. I haven’t yet got much experience  
> building Web Services, but I know enough high-level that this is the way to  
> go, we just need to make it happen.

My instinctive response is that a webservice is NOT the right way to do  
this.  
A webservice would be useful for communicating between multiple  
machines/processes, or between multiple languages. We certainly do not  
have  
the latter, and while the multiple process/machines do exist, for the  
engines  
I’m aware of, there’s no reason to not simply communicate in ruby using  
Ruby.  
Webservices just make it complicated.

There might be value in an engine publishing it’s API as webservice, but  
let’s  
start with a Ruby API.

David

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 5, 2006, 9:43pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/13 "2006-03-05T21:43:47Z")

</div>

On Sun, 5 Mar 2006 14:51:17 -0500  
David C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Maybe I’m very wrong, but engines are not services. They are more than that,  
> because services don’t generally have a UI.

A service with a UI is, by definition, a service 😉

In the traditional variant of MVC (not web oriented)  
the couple Model+Ctrl offers a service.  
The View is observing the Model and showing aspects of its state.

In principle delegation works very well with the MVC pattern:  
given 2 MVC, A and B you can in general expect that if Ctrl-A invokes  
CTRL-B, then both Model-A and Model-B get modified.  
The View-A and view-B will react accordingly (and independently).

Try to imagine that B is the Login engine (changing the state of the  
logged-in variable) and A is somebody needing Login authorization and  
you’ll  
see that the original idea is not absurd or incompatible with the  
Engines idea.

> If you want to go create “J2EE for Ruby” (which is what it kind of sounds like  
> have at it, but don’t muck up engines in the process.

What was originally proposed is so much less than “J2EE for Ruby”!

Basically we are talking about a hash table holding references to the  
available engines that allows to use delegation instead of inheritance  
**when convenient**.

As Manuel H. was suggesting, we should just evaluate if the cost  
of  
saving some copy/past + small rewriting is worth the effort.

Nathaniel B. is going more in the “J2EE for Ruby” direction. This  
was not my original intention, but I can see good points in what he  
says.  
Of course a lot of discussion is necessary, but my first reaction  
is that if we have a well decoupled design, I think that the current  
Engines could easily and transparently run on top of Nathaniel’s  
framework.

- Mauro

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 6, 2006, 2:03am UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/14 "2006-03-06T02:03:39Z")

</div>

The disturbing thing about introducing a WS is that for one incoming  
HTTP  
request, you will have some arbitrary number of engines making yet  
another  
arbitrary number of Web Service requests. Because Web Service  
request/response pairs are performed over the same transport, you may  
wind  
up with a great, great deal of overhead.

My experience with Web Services is that they are great if 1) you can  
predict  
how many WS calls you need to make; and 2) you can live with the  
performance  
hit. Given that (1) is impossible if engines start talking to one  
another  
and (2) will always be an issue, I think Web Services is probably not  
the  
most appealing way to enhance engines.

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 6, 2006, 1:48am UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/15 "2006-03-06T01:48:34Z")

</div>

> > Though I do not agree completely with DHH’s opinion about high level  
> > components,  
> > I keep hearing about it, but never read it. Could you give me a  
> > pointer?

[http://www.loudthinking.com/arc/000335.html](http://www.loudthinking.com/arc/000335.html)  
[http://www.loudthinking.com/arc/000407.html](http://www.loudthinking.com/arc/000407.html)  
[http://www.loudthinking.com/arc/000528.html](http://www.loudthinking.com/arc/000528.html)

He has his points though he is a bit extreme.

> is simpler than the JVM. It means that it does more for me.  
> Of course. However, if you look at CORBA or SOAP then you see an  
> example of each a “feature complete” component architecture and  
> communication protocol. They are so complex that you need lots code  
> to get the simplest things done with them if you want to use all of  
> their features.

In my opinion it will be very very hard to create a framework/API  
that allows to bick 3 but not only 2 points of the magic triangle:

- flexibility
- power
- ease of use

If you want high flexibility, you might either end up with a beast of  
CORBA (picking power) or an API that does not really define anything  
and the amount of code you have to write to use it is “easy” but  
there is a lot to do.

> The approach you suggest could be OK if applied in a consistent way.  
> Yes, namespaces reduce the possibility of conflicts. We would need to  
> put _everything_ in a namespace, though, not only controllers but  
> also models, helpers etc. This would remove the “name conflict” errors.

However, another problem with highly componentized and distributedly  
developed software is the one of dependency. If component A depends  
on components B (version 1) and C (version 2). However, component B  
depends on version 3 of component D and component C depends on  
version 2 of component D. The versions 2 and 3 of component D are not  
compatible, though. _Bang_.

This is an analogy to Goedel’s Theorem: Every computer system that is  
complex enough to be of interest contains possibilities to create  
contradictions. (Sorry for the very rough paraphrase).

I know of my experience this happens all the time. If you use  
DarwinPorts under Mac Os X then you know this, too. 🙂

> > While these systems can reduce the complexity of huge systems you  
> > have to get over an “entry complexity barrier” - lest you invest more  
> > time planning and implementing the required overhead such systems  
> > bring than you save compared with rewriting.
> 
> You are right. My aim is to use the space for improvement that  
> we have _without loss of simplicity_. If there is not such a space,  
> I rather drop the topic.

In my opinion adding “power” to a system as “simple” as Rails will  
always add complexity. Rails allows you to create applications fast  
and “scales up” pretty well in means of “supportable complexity of  
your application”.

However, you always have to keep in mind that the developers of Rails  
are of the opinion that less code is better than more as well as that  
less functionality is better than more in most cases (that could be  
seen as one of the more revolutional points of so called “Web 2.0”).

So if you wanted to know what I would recommend:

1.) Put everything into its own namespace but don’t break the  
possibility of a global namespace. This would require huge changes in  
the Rails code base and understanding Rails code is a bit more  
complicated than I thought when I looked at it first. Sure, it can be  
done.

2.) Drop the “global service registry” approach of things. This will  
make thing infinitely complex. Make it the user’s responsibility to  
call things explicitely. Inversion of control might be a good thing  
for huge systems but it creates more problems than it solves for  
smaller systems IMO.

3.) Add a dependency system that allows you to install all  
dependencies, i.e. install the engines plugin when installing  
ActiveRBAC. This could be done with a “rails project gem  
repository” (minus the gem structure plus the Engine structure, of  
course). ./script/plugin is a good start.

4.) IMO the major one: Decide on a common layer for the most  
important things.

Rails offers almost everything you need but authentication IMO.  
Select one authentication and authorization framework (this does not  
have to be ActiveRBAC though I would really like to see that :)) - or  
merge serveral existing ones into the “one”. Maybe a common interface  
would be good here, too. But keep these interfaces informally  
described in documentation and don’t wrap them into their own layer.

Could everybody else give his opinion on what “common sub-application  
types” are the most important besides user and permission handling?

5.) Decide on best practice of how “big engines” should be structured  
so they are extensible. Create “the” Article,Image,File Management  
(CMS)/Wiki/Weblog/Image Gallery “base applications” on Engines. Make  
sure they are extensible and extensible in the same way.

Don’t overload applications. Maybe contain a unolingual and a  
multilingual branch of the CMS so people who need only to support on  
language don’t have to stick with the complexity.

You won’t solve everybody’s problem but if you solve the problem of  
80% of all this is not bad. If I could drop the effort of writing the  
CMS part (for static pages like imprint) once for all by simply using  
the default CMS Engine, I would do so.

I would not do so if there was no documentation, things were to  
complex (i.e. unnecessary stuff I won’t need and I can’t switch off).  
I would not use it if it was too simple and I could not extend it  
easily. I would love it if it did the basic things and I only had to  
hook in a “price” field for articles, for example.

This is very very hard because:

- Defining “best practice” for extending (and more important: for  
making the base things extensible) is hard since you don’t want to  
restrict anyone but you want to make things consistent.

- Making APIs consistent is hard. Most of the time I dislike other  
people’s code it is because I would have done it differently and  
using it does not seem natural at me and it is itching. Yes, that’s  
the “not built here syndrom”. You have to streamline the “core  
engines” programming so they feel the same to developers.

- You have to make things extensible easily. At the moment, you  
cannot easily add to Engine models without copy’n’pasting the old  
file. This has to change for the points described above to work.

- You have to force yourself to cut down the features. Adding  
features is easier than cutting them out again.

- People will bug you because they want a feature that is not  
included and you have to make clear to them that this is intended.

- You must have very clear and extensive documentation and Howtos.  
Writing documentation sucks. Everybody hates it so you will have to  
do this 🙂

Goodness, that’s much more than I wanted to ramble on that topic.

HTH

Manuel

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 7, 2006, 6:47pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/16 "2006-03-07T18:47:29Z")

</div>

Am 06.03.2006 um 22:55 schrieb Kevin O.:

> It seems to me that we already have a system for integrating the  
> various  
> engines, it’s called a ‘programmer’.
> 
> Seriously, I think the time and effort would be better spent on  
> developing a set of ‘best practices’ for engines so that they have a  
> consistent interface with the rest of the world. If we all conform  
> to a  
> reasonably uniform standard then a lot of the problems go away.

Yep: Convention over Configuration. The convention description would  
be pretty big for engines and components but something like it should  
suffice. 🙂

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 6, 2006, 2:48am UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/17 "2006-03-06T02:48:49Z")

</div>

On Sun, 5 Mar 2006 11:41:06 +0100, mauro cicio wrote:

> > Better would be things like Bill K.'s recent post on defining a common  
> > DSL for authentication.  
> > The service registry becomes Usenet and the Rails wiki.  
> > The protocol becomes “authors talk to each other”.  
> > The pointer is Google, and the naming convention is decided by  
> > the authors for any given service…
> 
> I am not familiar with Bill K.'s work, I’ll check it out.

The basic idea was “let’s have all the authentication engines/plugins  
use a  
common domain-specific language”. That way, an engine that depends on  
the  
presence of authentication doesn’t need to search a registry; it can  
just  
use the One True Permission Syntax and whatever engine is installed will  
do  
the work. We’ve already started down this road, as I believe all the  
current auth schemes create @current\_user. I wouldn’t imagine that any  
app  
author would install multiple, conflicting auth engines, so I don’t see  
a  
need for a service registry.

> Actually the whole topic started from your statement:
> 
> > > Another thing to think about: You want the engine to be easily  
> > > extensible without folks having to modify the actual engine files, or  
> > > cut-and-paste huge swaths of code.

Oh, God, what have I done! 🙂

I was just musing that the engine should be written with lots of small  
routines, so that it’s easy for end-user-developers (not other engines)  
to  
override specific methods by redefining them. As James pointed out,  
UserEngine and LoginEngine could do this if they were refactored. If  
each  
user\_controller.rb action were a series of function calls and a  
CONFIG-like  
hash of strings, rather than inline string manipulation and business  
rules,  
it’d be easy for a given app to change only the desired behaviors and  
strings.

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 6, 2006, 10:57pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/18 "2006-03-06T22:57:03Z")

</div>

It seems to me that we already have a system for integrating the various  
engines, it’s called a ‘programmer’.

Seriously, I think the time and effort would be better spent on  
developing a set of ‘best practices’ for engines so that they have a  
consistent interface with the rest of the world. If we all conform to a  
reasonably uniform standard then a lot of the problems go away.

Right now I would opt for cutting and pasting rather than have to deal  
with service discoveries and all that nonsense. The fact that I can’t  
figure out what you guys are talking about regarding web services & all  
that (only having a superficial knowledge in that area) suggests that  
the solution will be complex and confusing to the point where it may  
make engines very ‘un-rails-like’.

\_Kevin

---

<div class="post-metadata">

**Author:** ![maurocicio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e274bd/32.png) [@maurocicio](https://www.ruby-forum.com/u/maurocicio)\
**Post date:** [March 8, 2006, 10:52pm UTC](https://www.ruby-forum.com/t/engines-collaboration-was-dry-and-engines/75384/19 "2006-03-08T22:52:43Z")

</div>

Calico Web Info (whoever that is):

Perhaps a two-door approach would be best then: one for ruby access  
(back door) and one for WS access (front door).

If these two doors were coupled in a way that either 1) one produces  
the other, or 2) a DSL produces both, then we would have the best of  
Nathaniel’s suggestion, with the performance of your suggestion.

Duane J.  
(canadaduane)  
[http://blog.inquirylabs.com/](http://blog.inquirylabs.com/)
