Free Support Forum - aspose.com

Aspose Slides - Concurrency

Hi

​We have defined a Master Powerpoint template comprising of 30 slides. These 30 slides dont have dependenices on each other. So instead of sequentially rendering them we implemented them to be rendered parallely.

​1) We read the Master Template during startup of the server and cache it in memory.
​2) When a request comes for PPT Generation, we read the Presentation Object of the Master Template and extract the appropriate slide clone it, create a new Presentation and do the same for all the slides. Once the rendering is completed for all the slides, we merge them together and create the final powerpoint output. With this approach we are finding issues and this doesnt happen every time

​We get the following exception and this is not to do with a particular slide.

​java.lang.Thread.run(Thread.java:748)

at com.aspose.slides.Collections.Generic.Dictionary.addItem(Unknown Source)

at com.aspose.slides.Presentation.for(Unknown Source)

at com.aspose.slides.Shape.getUniqueId(Unknown Source)

at com.aspose.slides.adt.do(Unknown Source)

at com.aspose.slides.o3.do(Unknown Source)

at com.aspose.slides.a5.do(Unknown Source)

at com.aspose.slides.rc.do(Unknown Source)

at com.aspose.slides.aeb.do(Unknown Source)

at com.aspose.slides.aai.do(Unknown Source)

at com.aspose.slides.aai.do(Unknown Source)

at com.aspose.slides.z8.do(Unknown Source)

at com.aspose.slides.MasterSlideCollection.do(Unknown Source)

at com.aspose.slides.MasterSlideCollection.do(Unknown Source)

at com.aspose.slides.SlideCollection.addClone(Unknown Source) —> Issue happens when we do addClone

at com.bnymellon.cpe.platform.presentation.slides.TitleSlideBuilder.createTitleSlide(TitleSlideBuilder.java:39)

at com.bnymellon.cpe.platform.presentation.slides.TitleSlideBuilder.buildPresentation(TitleSlideBuilder.java:28)

at com.bnymellon.cpe.platform.presentation.slides.TitleSlideBuilder$$FastClassBySpringCGLIB$$15c2b1bc.invoke(<generated>)

at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)

at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)

at com.bnymellon.cptservices.logging.util.LoggingAspect.presentationSlidelog(LoggingAspect.java:227)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)

at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)

at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)

at com.bnymellon.cpe.platform.presentation.slides.TitleSlideBuilder$$EnhancerBySpringCGLIB$$7bd616b1.buildPresentation(<generated>)

at com.bnymellon.cptservices.presentation.engine.PresentationRenderingTaskDefinitionServiceImpl.createTitleSlide(PresentationRenderingTaskDefinitionServiceImpl.java:95)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)


​Code for Creating the Cache - Simple In Memory Hashmap which is built during startup

​Cache class
​public class MasterPptCache {

private MasterPptCache() {

}

private static class SingletonHelper {

private static final MasterPptCache INSTANCE = new MasterPptCache();

}

public static MasterPptCache getInstance()

{

return SingletonHelper.INSTANCE;

}

private static Map<String,Presentation> presentationsMap = null;

public synchronized final void addPresentationToCache(String templateName, Presentation presentation)

{

if(presentationsMap == null)

{

presentationsMap = new HashMap<String,Presentation>();

presentationsMap.put(templateName, presentation);

}

}

public final Presentation getMasterPptCache( String templateName) {

Presentation presentation = null;

if(presentationsMap !=null && presentationsMap.size() > 0)

{

presentation = presentationsMap.get(templateName);

}

return presentation;

}

public final void clearPresentationsFromCache()

{

if(presentationsMap != null)

{

presentationsMap.clear();

}

presentationsMap = null;

}

public final boolean isCacheEmpty()

{

if(presentationsMap != null && presentationsMap.size() > 0)

return true;

else

return false;

}

public final int getCacheSize()

{

if(presentationsMap != null && presentationsMap.size() > 0)

return presentationsMap.size();

else

return 0;

}
}


​Cache loaded during startup

​private void loadCPTTemplates()

{

ClassLoader classloader = Thread.currentThread().getContextClassLoader();

URL url = classloader.getResource(“templates/”);
String sPath = url.getPath();
String path = sPath + “built-in/”;

​MasterTemplate.ppt is a 3MB file with 30 slides
Presentation presentation = new Presentation(path + “MasterTemplate” + “.ppt”);
MasterPptCache.getInstance().addPresentationToCache(Constants.CPT, presentation);

}

​-----------------------------------------------------------------------------------------------------------------------------------

​Lofig for Rendering a particular slide

​ private Presentation createTitleSlide(PresentationMetadata presentationMetadata) throws DocumentGenerationException {

Instant startTime = Instant.now();

Presentation presentation = new Presentation();

presentation.getSlides().removeAt(0);

if(MasterPptCache.getInstance().getMasterPptCache(Constants.CPT) != null)

System.out.println("Retrieving Slides from Cache "+MasterPptCache.getInstance().getMasterPptCache(Constants.CPT).getSlides().size());

Presentation masterPresentation = MasterPptCache.getInstance().getMasterPptCache(Constants.CPT);

presentation.getSlides().addClone(masterPresentation.getSlides().get_Item(MasterPresentationOrder.TITLE_SLIDE.ordinal())); // Issue happens here when we do addCLone

try{
ISlide sld = presentation.getSlides().get_Item(0);
ITable tbl = null;
CoverSlideOptions coverSlideOpts = presentationMetadata.getSections().getCoverSlide().getOptions();
List <Attendees> attendeeList = coverSlideOpts.getAdditionalAttendees();
for (IShape shp : sld.getShapes())

if (shp instanceof ITable)
tbl = (ITable) shp;
else if(shp instanceof IAutoShape){

IAutoShape autoShape = (IAutoShape)shp;

if(autoShape.getAlternativeText().equalsIgnoreCase(“TitleSlide_Date”)){

DateFormat df = new SimpleDateFormat(“MMMM dd, yyyy”);

String presentationDate = presentationMetadata.getSummary().getPresentationDate();

SimpleDateFormat formatter = new SimpleDateFormat(“MM/dd/yyyy”);

autoShape.addTextFrame((df.format(formatter.parse(presentationDate))));

}

if (autoShape.getAlternativeText().equalsIgnoreCase(“TitleSlide_Presenter”)) {

String content = coverSlideOpts.getPpmDisplayName().toUpperCase() + “\n” + coverSlideOpts.getPpmTitle();

autoShape.addTextFrame(content);

}

if(autoShape.getAlternativeText().equalsIgnoreCase(“TitleSlide_Attendees”) && attendeeList != null && attendeeList.size()>0){

String attendees = “\n”;

for(Attendees attendee:attendeeList){

if(attendee.getAttendeesName() != null){

attendees += attendee.getAttendeesName().toUpperCase() + “\n”+attendee.getAttendeesTitle()+"\n\n";

}

}

autoShape.addTextFrame(attendees);

}

if(autoShape.getAlternativeText().equalsIgnoreCase(“TitleSlide_PreparedFor”)){

autoShape.addTextFrame("Prepared for: "+presentationMetadata.getSummary().getName());

}
}

}catch(Exception e){

e.printStackTrace();

}

AppLog.info(“Time taken to create title presentation ::”

+Duration.between(startTime, Instant.now()).toMillis());

return presentation;
}

@BNYMellonITAMSoftwareOperation,

I have observed your comments. Can you please share sample project along with source files and environment details so that we may further investigate to help you out.

I have shared u all the details in the form of code. I dont have a standalone project setup for this and at this point we dont have time to do so.

@BNYMellonITAMSoftwareOperation,

I have observed your comments and request you to please share a working sample project along with source presentation reproducing the issue on your end. In order to proceed further with investigation, we need the requested information. Moreover, I also suggest you to please try using latest Aspose.Slides for Java 18.8 on your end as well first.