Last active
August 29, 2015 14:08
-
-
Save uklance/88c9a5400872273d9b14 to your computer and use it in GitHub Desktop.
Tapestry - Render body in parallel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<t:parallel> | |
<t:someComponent /> | |
</t:parallel> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.foo.bar.components; | |
public class Parallel { | |
@Inject ComponentResources componentResources; | |
@Inject TypeCoercer typeCoercer; | |
@Inject PerThreadManager perThreadManager; | |
@Inject ParallelManager parallelManager; | |
@Inject Logger logger; | |
public boolean setupRender(MarkupWriter markupWriter) { | |
Block bodyBlock = componentResources.getBody(); | |
final RenderCommand bodyCommand = typeCoercer.coerce(bodyBlock, RenderCommand.class); | |
final Element newDiv = markupWriter.element("div"); | |
markupWriter.end(); | |
final Thread parentThread = Thread.currentThread(); | |
Runnable task = new Runnable { | |
public void run() { | |
try { | |
parallelManager.setParentThread(parentThread); | |
MarkupWriterImpl parallelWriter = new MarkupWriterImpl(); | |
RenderQueueImpl parallelQueue = new RenderQueueImpl(logger); | |
bodyCommand.render(parallelWriter, parallelQueue); | |
Element rootElement = parallelWriter.getDocument().getRootElement(); | |
for (Node node : rootElement.getChildren()) { | |
// hopefully this doesn't cause a concurrent modification exception | |
node.moveToBottom(newDiv); | |
} | |
} finally { | |
parallelManager.taskFinished(task); | |
perThreadManager.cleanupThread(); | |
} | |
} | |
}; | |
parallelManager.submitTask(task); | |
// return false to exit the normal render flow | |
return false; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The implementation of this class will be @Scope(ScopeConstants.PER_THREAD) | |
*/ | |
public interface ParallelManager { | |
// Submit a task to the thread pool and maintain a mechanism to wait for in waitForTasks() | |
Future<?> submitTask(Runnable task); | |
// this will allow waitForTasks() to finish when all tasks (for the current request) complete | |
void taskFinished(Runnable task); | |
// Since this service is PER_THREAD scoped, set a member variable | |
void setParentThread(Thread parentThread); | |
// A custom PerThreadManager could check this boolean | |
boolean isChildThread(); | |
// A custom PerThreadManager could delegate to the parent Thread's PerThreadValues somehow | |
Thread getParentThread(); | |
// The request thread will need to wait for all child tasks to complete before writing to the response | |
void waitForTasks(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment