Closed jbee closed 4 years ago
Can one of the admins verify this patch?
ok to test
This is causing failure when running a managed/remote arquilllian set-up. The BeforeClass runs in the client side and can't access the CDI API.
This looks like a bit of an issue in the spec, because it might be that a gauge is injected before it is actually registered (because gauges are registered lazily - when their owning bean is instantiated, which might be at an unpredictable point in time).
In SmallRye we solve this by injecting a sort of proxy gauge, which, when its getValue()
is called, performs a lookup in the registry to find the actual gauge, and calls it to get the actual value. And if that gauge still does not exist at the time when getValue()
is called on the injected proxy, the call to the proxy returns null.
I think the spec does not explain what should correctly happen in such case. Perhaps we could make this SmallRye behavior the "correct" one? I don't think just injecting a gauge should somehow "force" it to register, that would mean initializing the owning CDI bean, which could be unexpected fiddling with the bean's lifecycle.
I'd be happy with making the proxy the official solution. Although it is somewhat inconsistent with rest of metrics where a missing metric causes exceptions. Gauges would no longer have that and instead just fail "silently".
@Channyboy Thanks for testing it. I changed this PR to use the work-around with a dummy test that runs first. This should process the bean and make sure the actual tests that run as 2 and 3 work with gauge already present. Again I cannot really test this as I have no compliant implementation yet but I'd assume this should solve the issue.
Although it is somewhat inconsistent with rest of metrics where a missing metric causes exceptions. Gauges would no longer have that and instead just fail "silently".
I don't think it's inconsistent. If you @Inject
different metric types, it leads to registering that metric if it's not registered yet.
The only difference is that we can't "force register" a gauge because its lifecycle depends on the owning bean, so instead of forcing a registration, we just wait until it is registered elsewhere.
@jmartisk makes sense. Makes me even more in favour of making the proxy the official solution.
@donbourne WDYT about this behavior specification?
I suppose if we went that way, this PR would not be needed because a correct implementation would pass test as it is now.
The behavior suggested makes sense to me. Using a proxy seems to be the most obvious way to handle this as it ensures we can satisfy the needs for CDI injection before a CDI bean with the target gauge is first used.
Is there anything we would want to say in the spec about this, or should we just leave this to implementers to figure out?
Ha, it seems the spec currently says that you can't do @Inject @Metric
on gauges at all (https://github.com/eclipse/microprofile-metrics/blob/3.0-M2/spec/src/main/asciidoc/app-programming-model.adoc#field)
@Metric can only be used on injected fields of type Meter, Timer, Counter, and Histogram.
Obviously that's at odds with what the TCK verifies. I'll try to come up with an update to that.
This also misses SimpleTimer
.
I submitted https://github.com/eclipse/microprofile-metrics/pull/571 - AFAIU if accepted, it will replace this PR.
This was replaced by #571
The idea of using
@Before
to make sure the gauge gets registered before the test is running is flawed in the sense that the test is only successful if the gauge is successfully injected into the instance of the test class. This happens before@Test
and@Before
run so at that point the gauge does not exist should thegauge
field be injected first. Or maybe even if it is injected afterbean
it might not exist due to proxies.I have not tested the fix of using@BeforeClass
but I'd suspect this should force the usage ofbean
before the test class instance is injected and thereby making sure the gauge exists so it is successfully injected into the test class instance.Another idea to fix this is touse a empty test method an annotate it with@InSequence(1)
and make the real tests 2 and 3.Signed-off-by: Jan Bernitt jaanbernitt@gmail.com