2013/7/30 Adam Murdoch [via Gradle] < ml-node+s1045684n5711550...@n5.nabble.com>
> > On 29/07/2013, at 4:25 PM, Alex Ruiz <[hidden > email]<http://user/SendEmail.jtp?type=node&node=5711550&i=0>> > wrote: > > Thanks, Adam. I've been looking into (and debugging) how the current API > for retrieving models work, to have a better understanding on how the API > and implementation of this new action would look like. > > Attila: This approach may also benefit your work on Netbeans. Please take > a look. > > This is what I have in mind, based on what I have done this weekend: > > - The action interface can be simple, and so far this is what I think > about its API: > > public interface ConsumerAction<T> extends Serializable { > T execute(Project project); > } > > where Project is a org.gradle.api.Project. My understanding is that by > having a Project we can do everything we need (through > Project#getService()). > > > The action should accept something other than `org.gradle.api.Project`, > for a few reasons: > > 1. `org.gradle.api.Project` is not version-independent. The entry point > for the action should be a function of the client's tooling API version, > not target Gradle version. > 2. Some actions don't need a configured project. For example, an action > may just be interested in the project hierarchy or the build environment. > Or it may not be interested in the tasks of a project, or the dependencies > of a project, or whatever. Instead, we need an interface that implies no > configuration is done, except for that which is explicitly requested by the > action. > 3. It's not going to work well with decoupled project mode (e.g. parallel > execution, configure on demand). This will become the default at some > point. The plan there is that there will be no way to navigate from one > project to another. Instead, we need an interface which provides access to > the whole build, but in a way that allows things like parallel > configuration and configuration on demand. > 4. There's no opportunity to cache models. We'd have to cache the whole > project model, which is unlikely to be possible any time soon. > > It would be very convenient to have access to `org.gradle.api.Project` regardless. Not being version independent is not necessarily a problem, since Gradle has to maintain compatibility due to the build scripts and this compatibility should be enough. Actually, I could provide a lot better experience in NB if this was possible. For example, I could easily display all the source root with proper classpaths including the usual "integTest" sources. Caching can be done external to Gradle. Actually, I already cache models. Also, there is no way to know in general if reevaluation of a project is necessary, so I believe that Gradle cannot do considerably better than an external process. Anyway, I find the "invocation" API your are proposing a good general concept. > So, instead, I'd introduce a new 'invocation' API. The contract would be > that we start with an empty model and execute the action. The action can > then use the invocation API to access the things it needs and these would > be populated on demand. > > There's probably 2 basic things the API would need to do: > > 1. Give me the set of all the projects in the build. This would return > something like `GradleProject` minus the tasks. It implies that the > settings script has been executed. > 2. For a given project, give me the model of type M. > > Possibly the API might also allow tasks to be scheduled and executed as > well, but that can happen later. > > > - The tooling API can have this method in ProjectConnection: > > <T> ConsumerActionExecutor<T> execute(ConsumerAction<T> action); > > where ConsumerActionExecutor is: > > public interface ConsumerActionExecutor<T> extends LongRunningOperation { > T get(); > } > > This API sort of follows the pattern of ProjectConnection#model(Class). > > > This is good. > > > From here, I'm looking on how to implement what goes in between > ProjectConnection#execute(ConsumerAction) and ConsumerActionExecutor#get() > . > > > There are some pretty deep changes here. I have some time to help out at > the moment if you'd like me to pick up some (or most) of this. > > Here a potential implementation plan: > > 1. Add the APIs and a dummy implementation that runs the action in the > tooling API client and returns the result. > 2. Pass the action across the cross-version layer into the provider. Move > the dummy implementation into the provider. > 3. Serialize the action across to the daemon and the result back. Move the > dummy implementation into the daemon. Now we've got a round trip into the > real process. > 4. Add an initial implementation of the invocation API, which simply > configures all projects before doing anything. > 5. Handle the case where the result references one of the models returned > by the invocation API. > > Why is 5 a special case? Aren't they serializable already? > At this point, you've got a solution to your problem, as you can now do a > single pass over the model and collect up the bits you need and send them > back to the client. Later steps can make this better: > > 1. Don't configure a project until one of its models is requested. > 2. Don't configure the project hierarchy until it is requested. > 3. Don't configure the tasks of a project until they are requested > > And generally making the invocation API richer. > > > I have created an initial draft for the required interfaces: https://gist.github.com/kelemen/6111321. See if you like it and what needs to modified, what is missing, or if it is completely wrong. Also, before actually executing this `ConsumerAction`, I need to know the version of Gradle if I can attempt to execute a `ConsumerAction` and fallback to what I do currently for versions older than 1.8. For which, it would be nice if there was a method to compare version numbers of Gradle. -- View this message in context: http://gradle.1045684.n5.nabble.com/Proposal-for-retrieving-multiple-types-of-models-from-a-project-in-a-single-pass-using-the-Tooling-AI-tp5711516p5711554.html Sent from the gradle-dev mailing list archive at Nabble.com.