dreedyman / Rio

Rio is an open source technology that provides a dynamic architecture for developing, deploying and managing distributed systems composed of services.
Apache License 2.0
21 stars 17 forks source link

Allow fine grained update of services in a deployment #10

Open dreedyman opened 11 years ago

dreedyman commented 11 years ago

Consider I deploy the following (pseudo) opstring (for argument's sake, file-based deployment in the Rio deployments directory):

deployment(name:'My Deployment') { service(name: 'Service A') { interfaces { classes 'com.my.A' artifact ref: 'a-dl' }

 implementation(class:'com.my.AImpl') 
 { 
     artifact ref: 'a' 
 } 

 maintain 1 

}

service(name: 'Service B') { interfaces { classes 'com.my.B' artifact ref: 'b-dl' }

 implementation(class:'com.my.BImpl') 
 { 
     artifact ref: 'b' 
 } 

 maintain 1 

} }

And I then make a change to Service B. Now, most changes people are likely to make over time is to simply refer to a newer version in the artifact declaration, but let's consider a more explicit change of implementation class. So I change the opstring, and Rio's deployment scanner picks up the updated file:

deployment(name:'My Deployment') { service(name: 'Service A') { interfaces { classes 'com.my.A' artifact ref: 'a-dl' }

 implementation(class:'com.my.AImpl') 
 { 
     artifact ref: 'a' 
 } 

 maintain 1 

}

service(name: 'Service B') { interfaces { classes 'com.my.B' artifact ref: 'b-dl' }

 // Implementation class Changed 
 implementation(class:'com.my.alt.AlternativeBImpl') 
 { 
     artifact ref: 'b-alt' 
 } 

 maintain 1 

} }

Is it reasonable to assume that my instance of A will not be destroyed / re-created, but that only B will? Now, consider A having an association to B, as follows:

deployment(name:'My Deployment') { service(name: 'Service A') { interfaces { classes 'com.my.A' artifact ref: 'a-dl' }

 implementation(class:'com.my.AImpl') 
 { 
     artifact ref: 'a' 
 } 

 association( type: 'requires', serviceType: 'com.my.B', 

property: 'b', name: 'Service B')

 maintain 1 

}

service(name: 'Service B') { interfaces { classes 'com.my.B' artifact ref: 'b-dl' }

 implementation(class:'com.my.BImpl') 
 { 
     artifact ref: 'b' 
 } 

 maintain 1 

} }

If I then re-deploy with a changed B (as in the previous example), is it still safe to assume that A will be left intact, and that it will simply be associated with a new B thereafter?

if I may dwell on a previously-mentioned detail, a very typical requirement will be to change a deployment to refer to a newer version of an artifact (say after a bugfix) - so a new opstring will be deployed where nothing but the artifact identifier has changed (e.g. "com.my:artifact:1.1" -> "com.my:artifact:1.2"). What would the redeployment behaviour be in this case?

In an environment where we have a number of core services running, with several customisations / additions for each of our clients, we are trying a strategy where we have a single opstring for the core environment (specifying all the services and SLAs) and a single opstring for each client (specifying all additional services and SLAs). There would be a certain elegance to a single set of deployment requirements, totally separate from the code base. We are thus not following the typical example model where every service specifies its own opstring, instead building libraries of components which separate opstrings may "draw from". In such an approach, it's vital that we can change the deployment requirements, without unnecessarily destroying a large number of services that have not changed.