feat(renderer): Add clear method to RendererWorkingSet for producer cleanup
This commit is contained in:
@@ -18,6 +18,8 @@ public interface RendererWorkingSet {
|
|||||||
|
|
||||||
Map<String, RenderingBo> commit(Class<? extends AbstractClientModule> producer, boolean clone);
|
Map<String, RenderingBo> commit(Class<? extends AbstractClientModule> producer, boolean clone);
|
||||||
|
|
||||||
|
void clear(Class<? extends AbstractClientModule> producer);
|
||||||
|
|
||||||
void getLiveSet(List<RenderingBo> combinedLiveSet);
|
void getLiveSet(List<RenderingBo> combinedLiveSet);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,21 +74,21 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
|
|||||||
|
|
||||||
final var previousWorkMap = previousWork.get();
|
final var previousWorkMap = previousWork.get();
|
||||||
if (previousWorkMap != null) {
|
if (previousWorkMap != null) {
|
||||||
final var releasedBoClasses = this.obtainSetFromPool();
|
this.releaseBoClasses(previousWorkMap);
|
||||||
for (final RenderingBo renderingBO : previousWorkMap.values()) {
|
|
||||||
if (releasedBoClasses.add(renderingBO.getClass())) {
|
|
||||||
renderingBO.closeStatic();
|
|
||||||
}
|
|
||||||
this.rendererBoPool.release(renderingBO);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.returnMapToPool(previousWorkMap);
|
|
||||||
this.returnSetToPool(releasedBoClasses);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rendererWork.next();
|
return rendererWork.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear(final Class<? extends AbstractClientModule> producer) {
|
||||||
|
final RendererWork rendererWork = this.workingSet.remove(producer);
|
||||||
|
if (rendererWork != null) {
|
||||||
|
this.releaseBoClasses(rendererWork.live());
|
||||||
|
this.releaseBoClasses(rendererWork.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getLiveSet(final List<RenderingBo> combinedLiveSet) {
|
public void getLiveSet(final List<RenderingBo> combinedLiveSet) {
|
||||||
this.workingSet.values().forEach(rendererWork -> combinedLiveSet.addAll(rendererWork.live().values()));
|
this.workingSet.values().forEach(rendererWork -> combinedLiveSet.addAll(rendererWork.live().values()));
|
||||||
@@ -98,6 +98,23 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
|
|||||||
return this.workingSet.computeIfAbsent(producer, k -> new RendererWork(this.obtainMapFromPool(), this.obtainMapFromPool()));
|
return this.workingSet.computeIfAbsent(producer, k -> new RendererWork(this.obtainMapFromPool(), this.obtainMapFromPool()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void releaseBoClasses(final Map<String, RenderingBo> work) {
|
||||||
|
if (work == null || work.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final var releasedBoClasses = this.obtainSetFromPool();
|
||||||
|
for (final RenderingBo renderingBO : work.values()) {
|
||||||
|
if (releasedBoClasses.add(renderingBO.getClass())) {
|
||||||
|
renderingBO.closeStatic();
|
||||||
|
}
|
||||||
|
this.rendererBoPool.release(renderingBO);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.returnMapToPool(work);
|
||||||
|
this.returnSetToPool(releasedBoClasses);
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, RenderingBo> obtainMapFromPool() {
|
private Map<String, RenderingBo> obtainMapFromPool() {
|
||||||
var map = this.mapsPool.poll();
|
var map = this.mapsPool.poll();
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
|
|||||||
@@ -146,6 +146,54 @@ public class RendererWorkingSetImplTest {
|
|||||||
assertTrue(live.isEmpty());
|
assertTrue(live.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void clearRemovesProducerAndReleasesWork() {
|
||||||
|
final var bo1 = new TestBoA();
|
||||||
|
bo1.setId("bo1");
|
||||||
|
final var bo2 = new TestBoB();
|
||||||
|
bo2.setId("bo2");
|
||||||
|
|
||||||
|
this.workingSet.add(TestModuleA.class, bo1);
|
||||||
|
this.workingSet.commit(TestModuleA.class, false);
|
||||||
|
this.workingSet.add(TestModuleA.class, bo2);
|
||||||
|
|
||||||
|
// Before clear
|
||||||
|
final List<RenderingBo> liveBefore = new ArrayList<>();
|
||||||
|
this.workingSet.getLiveSet(liveBefore);
|
||||||
|
assertTrue(liveBefore.contains(bo1));
|
||||||
|
assertNotNull(this.workingSet.get(TestModuleA.class, "bo2"));
|
||||||
|
|
||||||
|
this.workingSet.clear(TestModuleA.class);
|
||||||
|
|
||||||
|
// After clear
|
||||||
|
final List<RenderingBo> liveAfter = new ArrayList<>();
|
||||||
|
this.workingSet.getLiveSet(liveAfter);
|
||||||
|
assertTrue(liveAfter.isEmpty());
|
||||||
|
|
||||||
|
final var uncommittedAfter = this.workingSet.getUncommittedWork(TestModuleA.class);
|
||||||
|
assertTrue(uncommittedAfter.isEmpty());
|
||||||
|
|
||||||
|
verify(this.renderingBoPool, times(1)).release(bo1);
|
||||||
|
verify(this.renderingBoPool, times(1)).release(bo2);
|
||||||
|
assertEquals(1, bo1.closeStaticCalls());
|
||||||
|
assertEquals(1, bo2.closeStaticCalls());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void clearOnUnknownProducerDoesNothing() {
|
||||||
|
final RenderingBo bo1 = mock(RenderingBo.class);
|
||||||
|
when(bo1.getId()).thenReturn("bo1");
|
||||||
|
this.workingSet.add(TestModuleA.class, bo1);
|
||||||
|
this.workingSet.commit(TestModuleA.class, false);
|
||||||
|
|
||||||
|
this.workingSet.clear(TestModuleC.class);
|
||||||
|
|
||||||
|
final List<RenderingBo> live = new ArrayList<>();
|
||||||
|
this.workingSet.getLiveSet(live);
|
||||||
|
assertEquals(1, live.size());
|
||||||
|
assertTrue(live.contains(bo1));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void secondCommitReleasesPreviousLiveWorkAndCallsCloseStaticOncePerClass() {
|
void secondCommitReleasesPreviousLiveWorkAndCallsCloseStaticOncePerClass() {
|
||||||
final var bo1 = new TestBoA();
|
final var bo1 = new TestBoA();
|
||||||
|
|||||||
Reference in New Issue
Block a user