What Licensing Model Works Best for You

Ok, first off nothing in this post is official for what/how you can use a license. That is all set in the legal wording of our license agreement. I think this all is in line with that but I’m not a lawyer and so I may have something wrong.

Second, pricing against use is fundamentally our allocating our R&D costs, etc. across our customers. What we have always aimed for is to keep it simple. There are always more complex measuring systems that might be slightly “fairer”, but the added complexity would be such a PITA that it’s not worth it.

We now limit each license by the number of cores & threads. The limit is the same in a license, if you have a 4 core license it is also a 4 thread license. Using the example of a 4/4 core/thread license it works as follows:

  1. If the server has 4 or fewer cores, you can have as many threads, across as many JVMs/CLRs on that machine if you wish. The thread limit is ignored.
  2. If the server has more than 4 cores, you can only have a maximum of 4 threads generating reports. This limit is across all JVMs/CLRs on the system.
    1. The count starts when you call Report.ProcessSetup()/ProcessReport.processSetup() on the report object. The count ends when Report.ProcessComplete()/ProcessReport.processComplete() returns.
    2. If you try to run a 5th report in this case, Windward will throw an exception (which you can catch). Because of race conditions, when this occurs the count of allowed threads may drop to 3 until you bounce your system. So don’t run more threads than allowed.

So what does this mean for you?

If your server is spending a large part of its processing time generating reports, then get a license that is for the number of cores on your box. And create twice as many threads as cores for maximum throughput. This remains the best approach for heavy duty report generation.

If your report throughput is minimal and you have full control over the number of threads, go with the thread limit. This is useful for an application that runs on a 64 core server and generates 3 – 4 reports/day. Generate them sequentially and you will have no issues.

Web apps

With a web app (and other use cases) you have no control over the number of threads. Many web servers will create a thread for each session and you don’t want to refuse any sessions over your report limit – even if the web app is doing nothing but report generation. But we have two solutions here.

  1. Traffic cop approach. Keep your own count of the number of thread requests in process. If 4 are in process then on the 5th put your thread into a wait state on a semaphore. When any report completes, decrement the counter and signal the semaphore. The suspended thread will then resume and generate its report. We will provide sample code (Java & .net) for this soon.
  2. Throw to Javelin approach. Call our Javelin server with each report request and it will return the generated report.”You place Javelin on a server of your own where that server has the number of cores matching the Javelin license (so it can have unlimited threads).”
  3. Maybe we can… There is one other approach we are considering. We charge per report (and per page) against a server running on your system. But for each report it connects to our billing server so we can track reports run on our server. This approach will require a network communication for each report, but the communication will be one small message round trip so it should be fast.

And when we have 64,000 core servers

It’s coming. Moore’s Law is still in effect, but the win is now additional cores, not faster speed. I’ve sketched out how to break out report generation so it can use multiple threads to generate a single report. For all except applying the datasource the way we can break it out allows us to use a large number of threads (basically one per paragraph). And for the datasource, it is dependent on the selects in the tags but for most use we can have a thread per forEach iteration.

What does this mean? It means that running on a 64 core system a single report will be generated about 50 times faster. That means where before a 350 page report would take 50 seconds to be generated, it would now be 1 second. (note: If you need to generate 128 reports at the same time, then you won’t see this speed improvement – the win here comes when there are more cores than simultaneous report requests.)

But… How on earth do we price the licenses when we have this functionality?

Posted in Uncategorized | Comments Off on What Licensing Model Works Best for You

Roadmap version 12

I read recently that Intel does not do planning past 2 years. And they have to build billion dollar fabrication factories. We tend to stick to 6 months out because anything longer is not going to match where we are in 6 months. So here we are with what we plan to add over the course of version 12:

  1. Release Aardvarklytics (our iPad B.I. product).
  2. Javelin – Add some new features and provide it as a service on Azure.
  3. Engine & AutoTag – add support for cubes, direct connection to ERP systems (Dynamics, PeopleSoft, etc.), and Big Data systems.
  4. Greatly expand the functionality we support on PPTX.
  5. Word add: most remaining fields, locking parts of the document.
  6. Excel add: locking cells.
  7. Reviewing the entire wiki to make it easier to find the information you need.
  8. New videos where the U.I. has changed noticeably.

We’re also going to refactor the layout portion of the engine. This is the part that takes the complete report after the data is merged in, and lays it out on the page which is positioning, soft line & page breaks, etc. When we complete this you should not see any change. But it then gives us the ability to add support for items like footnotes.

As always, if you have questions please email or call me.

Flush the DbProviderFactories.Get FactoryClasses() cache

The first call to DbProviderFactories.GetFactoryClasses() reads in all classes from machine.config into an internal cache. All subsequent calls then use that cache and do not re-read from machine.config.

In AutoTag, if a connector is not installed, we provide the user a link to the connector. And once installed, a link to re-read the providers so they can continue using AutoTag connecting to the newly installed connector.

For this to work the cache has to be re-read by DbProviderFactories.GetFactoryClasses(). The following code forces a re-read.

/// <summary>
/// Force DbProviderFactories to re-read machine.config on the next call to DbProviderFactories.GetFactoryClasses().
/// </summary>
static public void FlushDbProviderFactoriesCache()
    FieldInfo initStateFieldInfo = typeof(DbProviderFactories).GetField("_initState", BindingFlags.Static | BindingFlags.NonPublic);
    if (initStateFieldInfo != null)
        ConnectionState state = ConnectionState.Closed;
        object initState = initStateFieldInfo.GetValue(state);
        if (initState is ConnectionState)
          state = (ConnectionState)initState;
          if (state != ConnectionState.Closed)
            initStateFieldInfo.SetValue(state, ConnectionState.Closed);
  catch (Exception)
    // nada
Posted in Uncategorized | Comments Off on Flush the DbProviderFactories.Get FactoryClasses() cache

We Tried, We Failed

I had this brilliant idea to powerwash this stencil around JavaOne & Oracle World.

Unfortunately… The City of San Francisco keeps their sidewalks so clean that the result was barely visible – if you looked very very closely. Worked great in Austin. Didn’t work in San Francisco.