RFI: concurrent fop instances -- use cases

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

RFI: concurrent fop instances -- use cases

Luis Bernardo

Hello,

I am investigating the possible caching of layout elements and as part of the investigation I realized that I need to understand how fop instances are managed in real life situations. In particular, I need to know if it is possible to have two concurrent fop instances created from the same fop factory.

This is a typical use case I am familiar with:
        FopFactoryBuilder builder = new FopConfParser(new File(confFile)).getFopFactoryBuilder();
        FopFactory fopFactory = builder.build();
        foreach (Doc doc : listOfDocs) {
            File fo = doc.getFOFile();
            File pdf = doc.getPDFFile();
            generateOutput(fo, pdf, fopFactory);
        }

where:

    public static void generateOutput(File fo, File pdf, FopFactory fopFactory) throws IOException, FOPException,
            TransformerException {
        OutputStream out = null;
        try {
            FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
            out = new FileOutputStream(pdf);
            out = new BufferedOutputStream(out);
            Fop fop = fopFactory.newFop(mime, foUserAgent, out);
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer();
            Source src = new StreamSource(fo);
            Result res = new SAXResult(fop.getDefaultHandler());
            transformer.transform(src, res);
        } finally {
            out.close();
        }
    }

In this case, even though a fop factory can create many fop instances we cannot have more than one in use at at given time.

Is anyone using a different approach where concurrent fop instances are possible?

Thanks,
Luis

Reply | Threaded
Open this post in threaded view
|

Re: RFI: concurrent fop instances -- use cases

Alexios Giotis
Hi Luis,

It is definitely possible to have different threads using Fop instances created from the same FopFactory. In fact, for me this is the typical usage. This is like replacing

>         foreach (Doc doc : listOfDocs) {
>             File fo = doc.getFOFile();
>             File pdf = doc.getPDFFile();
>             generateOutput(fo, pdf, fopFactory);

with

ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, ...);
for (Doc doc : listOfDocs) {
  executor.submit(new Runnable() {
            File fo = doc.getFOFile();
            File pdf = doc.getPDFFile();
            generateOutput(fo, pdf, fopFactory);
  }
}

It is used to reduce the time required to generate thousands or millions of documents.

Fop instances can also be generated from different FopFactory instances. This is a workaround I used in the past to avoid some FOP concurrency issues. The drawback is increased memory usage and warm-up time as FOP caches are referenced from a FopFactory instance.


Alex Giotis



On 1 Jul 2013, at 15:14, Luis Bernardo <[hidden email]> wrote:

>
> Hello,
>
> I am investigating the possible caching of layout elements and as part of the investigation I realized that I need to understand how fop instances are managed in real life situations. In particular, I need to know if it is possible to have two concurrent fop instances created from the same fop factory.
>
> This is a typical use case I am familiar with:
>         FopFactoryBuilder builder = new FopConfParser(new File(confFile)).getFopFactoryBuilder();
>         FopFactory fopFactory = builder.build();
>         foreach (Doc doc : listOfDocs) {
>             File fo = doc.getFOFile();
>             File pdf = doc.getPDFFile();
>             generateOutput(fo, pdf, fopFactory);
>         }
>
> where:
>
>     public static void generateOutput(File fo, File pdf, FopFactory fopFactory) throws IOException, FOPException,
>             TransformerException {
>         OutputStream out = null;
>         try {
>             FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
>             out = new FileOutputStream(pdf);
>             out = new BufferedOutputStream(out);
>             Fop fop = fopFactory.newFop(mime, foUserAgent, out);
>             TransformerFactory factory = TransformerFactory.newInstance();
>             Transformer transformer = factory.newTransformer();
>             Source src = new StreamSource(fo);
>             Result res = new SAXResult(fop.getDefaultHandler());
>             transformer.transform(src, res);
>         } finally {
>             out.close();
>         }
>     }
>
> In this case, even though a fop factory can create many fop instances we cannot have more than one in use at at given time.
>
> Is anyone using a different approach where concurrent fop instances are possible?
>
> Thanks,
> Luis
>

Reply | Threaded
Open this post in threaded view
|

Re: RFI: concurrent fop instances -- use cases

Luis Bernardo
Thanks Alex. Your example (different threads using Fop instances created from the same FopFactory) is exactly the use case I was wondering whether is was possible.


On Mon, Jul 1, 2013 at 3:35 PM, Alexios Giotis <[hidden email]> wrote:
Hi Luis,

It is definitely possible to have different threads using Fop instances created from the same FopFactory. In fact, for me this is the typical usage. This is like replacing

>         foreach (Doc doc : listOfDocs) {
>             File fo = doc.getFOFile();
>             File pdf = doc.getPDFFile();
>             generateOutput(fo, pdf, fopFactory);

with

ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, ...);
for (Doc doc : listOfDocs) {
  executor.submit(new Runnable() {
            File fo = doc.getFOFile();
            File pdf = doc.getPDFFile();
            generateOutput(fo, pdf, fopFactory);
  }
}

It is used to reduce the time required to generate thousands or millions of documents.

Fop instances can also be generated from different FopFactory instances. This is a workaround I used in the past to avoid some FOP concurrency issues. The drawback is increased memory usage and warm-up time as FOP caches are referenced from a FopFactory instance.


Alex Giotis



On 1 Jul 2013, at 15:14, Luis Bernardo <[hidden email]> wrote:

>
> Hello,
>
> I am investigating the possible caching of layout elements and as part of the investigation I realized that I need to understand how fop instances are managed in real life situations. In particular, I need to know if it is possible to have two concurrent fop instances created from the same fop factory.
>
> This is a typical use case I am familiar with:
>         FopFactoryBuilder builder = new FopConfParser(new File(confFile)).getFopFactoryBuilder();
>         FopFactory fopFactory = builder.build();
>         foreach (Doc doc : listOfDocs) {
>             File fo = doc.getFOFile();
>             File pdf = doc.getPDFFile();
>             generateOutput(fo, pdf, fopFactory);
>         }
>
> where:
>
>     public static void generateOutput(File fo, File pdf, FopFactory fopFactory) throws IOException, FOPException,
>             TransformerException {
>         OutputStream out = null;
>         try {
>             FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
>             out = new FileOutputStream(pdf);
>             out = new BufferedOutputStream(out);
>             Fop fop = fopFactory.newFop(mime, foUserAgent, out);
>             TransformerFactory factory = TransformerFactory.newInstance();
>             Transformer transformer = factory.newTransformer();
>             Source src = new StreamSource(fo);
>             Result res = new SAXResult(fop.getDefaultHandler());
>             transformer.transform(src, res);
>         } finally {
>             out.close();
>         }
>     }
>
> In this case, even though a fop factory can create many fop instances we cannot have more than one in use at at given time.
>
> Is anyone using a different approach where concurrent fop instances are possible?
>
> Thanks,
> Luis
>