Hi Marc,

different languages have feature like the annotation you are describing. Most of these have one thing in common: they are quite young. Especially compared to M/COS.
That being said, some of the functionality you are envisioning is there already. Well, kinda, sorta ;)

You can use ZBREAK to add hooks to your existing code (even already compiled ones). This is more comparable to introspection than annotation as it happens at runtime. However, with the ZBREAK execute_code parameter it is easy to do anything from any point in your code.

To actually implement annotations the way you are thinking of here, you'd need to implement a wrapping solution around the compiler.
You might be able to hook into the source control utilities to do that: extending studio, however, modifying the sourcecode before passing it to the compiler would be difficult.

Using the wrapper approach, you could programmatically create shadow classes of your actual code and insert your annotation's code.
This will come with the drawback that you'd have to invoke your shadow classes instead of the direct code.
On the other hand it would allow you to have the annotations optional, so you're not slowing down your application once you're done developing.

You could possibly also use generator methods to move the wrapping into the class and generate new methods based on the code you put in and the annotations you added.

HTH,
Fab

Hi Mack,

there isn't an easy answer for this. The amount of storage heavily depends on how your data and your global structure can be compressed. In storing your globals there are a number of mechanisms that optimize the storage used. It might be useful to have a look at some of the internal mechanisms for that: https://community.intersystems.com/post/internal-structure-cach%C3%A9-database-blocks-part-1.

As you can see from this article (which is still pretty high level), it won't be easy to create an accurate prediction mechanism.

As such, the best way to try this out, would be to just use a small amount of your source data and store it in Caché. This will give you a baseline of how much overhead you can expect. Depending on your data structures there might also be additional indices being created.

So if you try and store 10MB,100MB,1GB,1TB of your source data on a test system, you'll be able to get a pretty good prediction curve out of it with a low error rate.
Any other approach either is going to be too much guesswork, or going to need a lot more detailed work, so it would probably not be worth the time.

I tried to include an actual path forward for you, so I hope this helps!

HTH,
Fab

Not enough information: What else is involved here? Mirroring? Shadowing? How is your namespace setup? Do you have routine mappings? Is it all the queries? Only some? Since when are you seeing the issue? What changed?

You could look at the journal files to see what/if the methods are being changed from another service.  

You might want to consider opening up a WRC issue to get help tracking this down!

-Fab

Just a little addition: 

2.5) Your cached query is messed up. 

This comes up from time to time (and imho much more often than 3-7) ;)  

Typical symptoms: slightly different (new) queries DO return data; depending of which incarnation of 'messed up' you are encountering, you might actually get an error instead of actual data. 

 

Cheers,

Fab

As Dmitry already pointed out, it seems you should cover your basics first. 

A CSP page is first and foremost a static page which is being rendered on the server. The data model of webpages has traditionally been dominated by a request-response approach. This comes down to the basic stateless design of http: a client sends requests to GET some information from the server (very simplified). 

This means it is quite difficult to "push" updates from the server to the client. One solution, or rather, workaround to this problem, is to implement a timer on the client side which periodically asks the server if there is new data. This can easily be solved with a javascript timeout. 

Nowadays we have moved on a little bit from this rather clumsy approach. Dmitry already mentioned a possibility for this: websockets. Websockets give you a two way communication channel between your client and your server (see RFC6455). 

This introduced the exciting possibility to actually push events from the server to the client without the need for periodic pulling of information.  

Have a look at this basic example how to do that in Caché technology: asynchronous-websockets-quick-tutorial (shameless plug;) )

There have been quite a few advances and developments in this area, building on the basic websocket connection and building frameworks for the efficient handling and caching of even bigger datasets. React/Flux are just some frameworks you could look at as you make your way through the jungle of web technology. Good Luck!

 

-Fab

Hi Jonathan,

unfortunately there is no easy way to do this from within Caché. The PDF format is a rather complex binary format and Caché doesn't have a library to access it.  There are a couple of tools that allow the annotation of PDF documents, but none of them would allow you to easily integrate with the engine. 

PDF is in itself a rather complex format, so to directly edit it, say via opening it as %BinaryStream, would require you to implement your own PDF rendering engine. (Have a look at [this post](https://blog.idrsolutions.com/2013/01/understanding-the-pdf-file-format-...) to get a glimpse of the problems you'd be facing)

The solution to use a PDF as background for the rendering of a new report via FOP might be a way out. But you'd need to know the layout of the incoming PDF and be sure it doesn't change. Only then you could get the ZEN report to print into specific fields. 

-Fab

Here is a simple example to upload and store a file via a csp page:

<html>
<head></head>
<body>

<form enctype="multipart/form-data" method="post" action="upload.csp">
    Enter a file to upload here: <input type=file size=30 name=FileStream>
    <hr />
    <ul><input type="submit" value="Upload file"></ul>
</form>

<csp:if condition='($data(%request.MimeData("FileStream",1)))'>
    <h2>Saving file...</h2>

</csp:if>
</body>
</html>