DefaultServiceRegistryTest.groovy

Clone Tools
  • last updated a few seconds ago
Constraints
Constraints: committers
 
Constraints: files
Constraints: dates
Revert "Revert "Merge remote-tracking branch 'origin/sg/merges/pr-9419'""

This reverts commit 0625bc7420e55e87730673231af6ad45dd04f47a.

  1. … 90 more files in changeset.
Revert "Revert "Merge remote-tracking branch 'origin/sg/merges/pr-9419'""

This reverts commit 0625bc7420e55e87730673231af6ad45dd04f47a.

  1. … 90 more files in changeset.
Revert "Merge remote-tracking branch 'origin/sg/merges/pr-9419'"

This reverts commit 2f79026f5e127a8175e25844522237615b19ed52 because of a performance regression,

reversing changes made to 7f1e66079ce629ecde3e09e549e9796ab85761dc.

  1. … 90 more files in changeset.
Fix DefaultServiceRegistry using '$' to indicate inner classes in errors

  1. … 1 more file in changeset.
Merge branch 'master' into deprecate_http_download

* master: (225 commits)

Document the purpose of PublicApi.kt

Mention Eclipse test sources as a potential breaking change in the upgrade notes.

Fixed managed property generation for `Property<T>` types where `T` is a parameterized type.

Update library/language versions used by build-init templates.

Remove the instant execution cache file when there is a failure writing to the cache file.

Disallow references to `ConfigurationContainer` from tasks serialized to the instant execution cache.

Recognize contributor

Publish 5.5-20190620010535+0000

Fix small typo in the feature variants chapter of the user guide

Rebaseline instant-execution performance tests

Refine MethodCodec

Polish task actions test

Polish BeanSchema

Temporarily ignore instant execution performance tests

Refine ClassLoaderCacheInternal

Tidy up DefaultInstantExecution & DefaultClassLoaderCache

Add some coverage for captured task actions

Dehydrate Closure and fix BeanSchema for task actions

Add MethodCodec for serializing StandardTaskAction

Let BeanSchema include AbstractTask.actions

...

Signed-off-by: Jonathan Leitschuh <Jonathan.Leitschuh@gradle.com>

    • -0
    • +34
    ./DefaultServiceRegistryTest.groovy
  1. … 14 more files in changeset.
Fix `Instantiator` service injection so that services of type `ServiceRegistry` can be injected into instantiated things. This was previously available for services created by the `DefaultServiceRegistry`.

Also disallow registration of services of type `ServiceRegistry` so that the automatically provided instances are always used.

    • -0
    • +34
    ./DefaultServiceRegistryTest.groovy
  1. … 2 more files in changeset.
Fix `Instantiator` service injection so that services of type `ServiceRegistry` can be injected into instantiated things. This was previously available for services created by the `DefaultServiceRegistry`.

Also disallow registration of services of type `ServiceRegistry` so that the automatically provided instances are always used.

    • -0
    • +34
    ./DefaultServiceRegistryTest.groovy
  1. … 2 more files in changeset.
Fix `Instantiator` service injection so that services of type `ServiceRegistry` can be injected into instantiated things. This was previously available for services created by the `DefaultServiceRegistry`.

Also disallow registration of services of type `ServiceRegistry` so that the automatically provided instances are always used.

    • -0
    • +34
    ./DefaultServiceRegistryTest.groovy
  1. … 2 more files in changeset.
WIP - more changes.

  1. … 9 more files in changeset.
WIP - more changes.

  1. … 9 more files in changeset.
Resolve additional failing tests

Signed-off-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>

  1. … 8 more files in changeset.
Change `DefaultServiceRegistry.getAll()` so that it does not return services from parents that have been decorated or overridden by the current registry.

Also change the interaction between parent and child registry so as to avoid assuming a particular parent implementation.

    • -48
    • +201
    ./DefaultServiceRegistryTest.groovy
  1. … 13 more files in changeset.
Change `DefaultServiceRegistry.getAll()` so that it does not return services from parents that have been decorated or overridden by the current registry.

Also change the interaction between parent and child registry so as to avoid assuming a particular parent implementation.

    • -48
    • +201
    ./DefaultServiceRegistryTest.groovy
  1. … 13 more files in changeset.
Spelling (#8199)

Fix several spelling issues.

    • -16
    • +16
    ./DefaultServiceRegistryTest.groovy
  1. … 36 more files in changeset.
Allow additional parameters for decorator methods.

There was an arbitrary distinction where decorator methods

could only take a single parameter (the service to decorate).

However in many cases we need additional services that help

with the decoration. This is now fixed and also simplifies the

code and documentation.

    • -0
    • +26
    ./DefaultServiceRegistryTest.groovy
  1. … 2 more files in changeset.
Fix deadlock when closing service registry

When a service registry was closing its child

while at the same time the child was looking up

a service in that parent, a deadlock could occur.

This was caused by the parent waiting for the child

to finish its pending requests, while the child could

not finish because it was waiting on the parent to

finish closing.

The whole "wait for pending requests" logic has been

removed. It was only used in one case where a service

was looked up while closing. This has been refactored

to look up the service at construction time instead and

use it during closing. Looking up services while closing

is now forbidden.

    • -0
    • +13
    ./DefaultServiceRegistryTest.groovy
  1. … 4 more files in changeset.
Some clarifying renames and cleanup

  1. … 1 more file in changeset.
Remove unneccessary objects from service registry

This minimizes the memory footprint of service registries

with the following improvements:

The isolation beteen parent and child is now handled by

explicitly checking whether a service came from the same

registry instead of wrapping services in an isolation layer.

The lookup cache has been removed, as the lookup algorithm

is now cheap enough to work without a cache.

The type spec concept has been removed and replaced by a

static "isSatisfiedBy(Type, Type)" method. The cache for the

specs was also removed as a result.

An array of services is only created if there are multiple

implementations for an interface.

Looking up Object.class is no longer supported and it is

no longer tracked as a potential service class.

    • -22
    • +26
    ./DefaultServiceRegistryTest.groovy
  1. … 2 more files in changeset.
Allow parallel service registry access

Instead of locking around every service access,

allow multiple threads to look up services at

the same time. This requires almost no coordination,,

as most of the state inside a registry is completely

independent of the rest. Every provider can protected its

own state without locking all the others. The only

coordination needed is when stopping, because we need

to ensure that all pending requests are served first.

This is achieved using a request counter.

  1. … 1 more file in changeset.
Find service cycles without spending heap memory

Instead of recording the services being requested

in an extra queue, throw an exception on a cycle

instead and enrich it as we go back up the stack.

This completely removes the cost of cycle detection

during normal operation while still giving us proper

error reporting when something goes wrong.

  1. … 1 more file in changeset.
Optimize ServiceRegistry

The service lookups were showing up as a hot spot in many

configuration time scenarios. The heart of the problem was

that OwnServices was doing too much work on a lookup - it

iterated over all providers, even if their raw type didn't

match the requested type. To work around that we had added

a "hasService" method as well as a CachingProvider in the

past. These somewhat mitigated follow-up requests, but only

made the problem worse on the first lookup of a service.

This change moves the analysis to service registering time.

Services are kept in a multimap structure that associates

them with their raw type. Only the providers with the right

raw type are asked on each lookup. After this change, the

"hasService" method and the CachingProvider were no longer

necessary, as the normal lookup was fast enough.

Another problem was that we created lots of garbage when

walking up the parent hierarchy on a "getAll" request. Each

layer would create a new array list to hold intermediate

results. This has been changed and we now pass the collecting

array from the lowest layer up the parent hierarchy.

The code that was handling cycles in service lookups used a

HashSet, which lead to two problems: We couldn't report the

actual cycle (since we lost the order) and we were paying

the price of hashing, which is not worth it for such tiny

collections. It now uses an ArrayDeque and a "contains" call

instead, which is more efficient and provides better error

reporting.

The handling of service dependencies was also using a HashSet,

which again lead to unnecessary hash operations. An ArrayList

works fine here and uses less CPU cycles.

Finally, CompositeStoppable was crazy expensive, because it used

a CopyOnWriteArrayList and added each Closable one by one. It now

uses simple synchronization instead, greatly reducing GC pressure.

In order to be able to use some of those data structures that are

Java 6+, I moved the Java version check earlier in the chain so we

don't try to set up any services before checking whether we run on

a supported Java version.

The whole DefaultServiceRegistry class should be broken up for

easier understanding, but I didn't go down that path yet to make

this change easier to review.

    • -14
    • +81
    ./DefaultServiceRegistryTest.groovy
  1. … 14 more files in changeset.
Polish `DefaultServiceRegistryTest`

    • -30
    • +30
    ./DefaultServiceRegistryTest.groovy
Optimize service registry performance

Our service registry infrastructure is far from being performant. Lookup by type is particularily expensive, and involves

looping through all supplied providers, and eventually go to the parent registries until we find a match, that we can cache.

This commit introduces a new method that allows a provider to tell if it is _candidate_ for providing a type (independently

of parameterized types), and introduces more caching of the result.

This improves performance of the service registry, at the cost of increased memory usage.

  1. … 7 more files in changeset.
Changed `DefaultServiceRegistry` to allow some wildcards to be used with locating services.

Services can be injected or located using `List<? extends T>` in addition to `List<T>`. Same for `Collection`.

    • -1
    • +49
    ./DefaultServiceRegistryTest.groovy
  1. … 1 more file in changeset.
Changed `DefaultServiceRegistry` to support injecting all services of a given type into a factory method.

A factory method can now have a parameter of type `List<T>` or `Collection<T>` to receive all services of type `T`.

Also changed the implementation of `get(Type)` to support `List<T>`.

    • -0
    • +84
    ./DefaultServiceRegistryTest.groovy
  1. … 1 more file in changeset.
Fix unit test.

Improve test assertions

    • -10
    • +18
    ./DefaultServiceRegistryTest.groovy
The decorator method of a ServiceRegistryProvider can now be prefixed with 'decorate' instead of 'create'

    • -23
    • +121
    ./DefaultServiceRegistryTest.groovy
  1. … 1 more file in changeset.
Once a service registry has been read from, do not allow any more additions.

    • -4
    • +65
    ./DefaultServiceRegistryTest.groovy
  1. … 1 more file in changeset.
Changed CompositeStoppable to fail if an instance has a close() or stop() method and does not implement Closeable or Stoppable. This is just a temporary step to flush out any services I missed. The check will go away entirely in a subsequent step.

    • -15
    • +12
    ./DefaultServiceRegistryTest.groovy
  1. … 2 more files in changeset.