Hi Marcel,

My biggest concern is that if we now choose that one OSGi container can only 
host one tenant, there is no way back. If we follow that path we will not 
design Amdatu to be tenant aware in its core, as there is always only one 
tenant hosted by the container. If for any reason (including the ones we do not 
oversee right now) we come to the conclusion that this was not a good choice 
later on, it will be quite a challenge to fix it. If on the other hand we 
design Amdatu in its core to deal with the fact that one container may host 
multiple tenants, we can have it both ways.

One of the use cases in which 1 tenant per container could be an issue is a 
customer we developed a solution for last year. The customer I'm talking about 
is an 'umbrella organization' for the catering industry. The organization 
provides services to catering entrepreneurs. One of those services is the 
hosting of their (basic and internal) website. Each entrepreneur may request 
such a website and will be provided with logins for he and his employees. The 
entrepreneur can provide a logo, add some text, define open and close times, 
etc. Such an entrepreneur is a good example of a tenant.
Of course, there are many entrepreneurs (in this case, we agreed to support up 
to 5000) and each one of them may request this website. The amount of data 
stored for each tenant is very limited; a logo, some text and some logins, bu 
tthat's about it. And so this was all hosted by a single application server. 
Many entrepreneurs requested such a website, but are not effectively using it. 
The single app server can host thousands of tenants without problems.
So assume in the Amdatu case we would launch a container for each tenant 
(including the ones that requested the site once but never actually use it). In 
this case most functionality is shared by all tenants, only a small piece of 
the application is tenant specific. So we would probably end up putting the 
tenant unware services on a separate container, and remote service calls would 
be all over the place as almost each method invocation needs to be remoted (or 
we install the service locally, but that would increase waste of resources).
There would be a lot of overhead starting separate containers for each tenant 
and remoting service calls as opposed to just one container with a few tenant 
aware services. Also managing (provisioning, updating) 1 container instead of 
5000 seems much easier, faster and less error-prone to me.
So by just looking at this use case I would say that one container serving all 
tenants would be the best solution, which is exactly the way we implemented it 
in this project.

Regarding the context; if we do not store context information in a Thread local 
variable and we do not want to pass around contextual properties in each method 
invocation; how would you determine contextual information? I discussed the 
Thread local stuff with Mark and Bram last week, but there just isn't an 
alternative. Any BLOG you read about Thread locals being so evil doesn't come 
with an alternative, or comes up with an alternative which in the end still 
uses Thread locals in its heart. So what would you suggest?

Regards, Ivo

-----Original Message-----
From: amdatu-developers-bounces at amdatu.org 
[mailto:[email protected]] On Behalf Of Marcel Offermans
Sent: maandag 3 januari 2011 11:23
To: amdatu-developers at amdatu.org
Subject: Re: [Amdatu-developers] Multi-tenancy (and more) design

On Jan 3, 2011, at 10:29 , Ivo Ladage-van Doorn wrote:

> First of all, I believe that we must accept the fact that there will be 
> situations in which multiple tenants are hosted by the same OSGi container. I 
> think there will be several use cases in which we cannot effort to start an 
> isolated container for each tenant, for resource consumption reasons or other.

Are you sure of that? Is the amount of data per tentant so small that the 
overhead of an extra container is actually the bulk of the data? If that is 
really the case, isn't your notion of a tenant way too fine grained in that 
case?

What other reasons?

> That means that we will have to deal with the fact that some services will be 
> tenant aware while others will not. If a developer creates a service that is 
> tenant aware, a separate service instance will be available for each tenant 
> within that container. For a tenant unaware service, there will be only one 
> service instance running to be used by any tenant.

Maybe.

> Now the problem is how service dependencies between tenant aware and unaware 
> services are resolved. If I created a tenant aware service and have a service 
> dependency on another service, I need to know if that service is tenant aware 
> as I need to define the 'tenantid' service property defining this dependency. 
> But it might be the case that at the time I programmed my tenant aware 
> service, this other service was not tenant aware but has been made tenant 
> aware later on. So that means that we need to think of a way that even for a 
> programmer, it is irrelevant if a service on which his service depends is 
> tenant aware or not. He should just get the proper tenant aware service 
> injected.

Another way of looking at this:

If a service is tenant unaware but it has dependencies on tenant aware 
services, you have just made it tenant aware by definition.

> <braindump>
> Now I think the 'context' I'm currently working on might be the/a solution to 
> this problem. In general a 'context' defines the context of an execution. In 
> case of a HTTP request for example, it is a 'request context' and the current 
> tenant could be resolved from the hostname and the current user from the 
> token cookie. In case of a scheduled job, the context is a 'job execution 
> context' and the job itself may define the tenant of that context. In case of 
> a remote service, the context should be send along with the rpc.
> Anyway, I think that there is always some 'context' and that context 
> determines, amongst many other things, the tenant that is 'active' in the 
> current method invocation.
> Now if a service is tenant ware, this just means that it reads the current 
> tenant from the available context and acts upon. This would add a little more 
> complexity to the implementation of a tenant aware service as upon each 
> method invocation it needs to pull this tenant information from the context, 
> but we could simplify that for example by using AOP (the tenant is an 
> aspect). However, if the context is available as a service (as I'm planning 
> to), retrieving the current tenant from the context is rather easy and might 
> do for the first implementation.
> </braindump>
> 
> Please let me know what you think of this brain dump and if it could 
> contribute to solving our 'tenant problem'.

I thought we already dismissed both using some kind of magic "context" stored 
in a thread local and passing the context around as a parameter to each and 
every method of a service.

As for AOP, I would not want to require everybody working with Amdatu to use 
that, nor would I want to use it in Amdatu itself. If AOP was such a great 
idea, it would have been part of Java and OSGi by now.

Greetings, Marcel


_______________________________________________
Amdatu-developers mailing list
Amdatu-developers at amdatu.org
http://lists.amdatu.org/mailman/listinfo/amdatu-developers

Reply via email to