I love this! I needed PubSub-like services for the concurrent tweets processing and control of workers in the twitter api streaming mode sample and at the moment there is fragile, simplistic locking  schema used. I suspect PubSub will be better/more reliable, so I'll try to play with your classes.

But here are 1 questions:

  • why you didn't upload them to your intersystems-ib github repo?
  • and why these strange package names - IAT.S04.* and IAT.S05.*?

P.S.

It would be really nice if you would explain more details about API usage: I understand that UMLExplorer diagrams created are obvious and self-explanatory (wink) but more documentation never hurts... 

Good question, it would be nice to know the list of supported (i.e. properly syntax highlighted) mimetypes.

I know that application/json is [almost] properly handled (with the exception of open brace). But what else? Even text/plain is marked invalid.

Class CPM.Sample.PackageDefinition Extends CPM.Utils.PackageDefinition
{

XData Package [ MimeType = application/json ]
{
{
        "name": "cpm-embedded-package-sample",
        "description": "CPM package sample with the embedded paсkage definition",
        "author": "tsafin",
        "version": "0.5.0",
        "license": "MIT",
        "dependencies": {
            "async": ">= 0.2.10",
            "fsplus": ">= 0.1.0",
            "language-cos": "https://github.com/UGroup/atom-language-cos.git"
        }
    }
}

} 

Yeah, that was bad surprise for me recently. I could connect from client via websocket to any CSP class name (which is good thing). But I have to create separate web-application if I want to connect to %CSP.REST handler (which was quite unexpected). If I would not create separate application with their own dispatcher class then I'd receive strange 403 error (not authorized). 

This inconsistent treating REST and websocket makes no much sense for me, but unfortunately this is the way things are in %CSP.REST

Paul, could you please disable radioactive because it's confusing and useless at the moment? 

Tight now, with so small traffic and counted active members we need full, unfiltered stream of posts sorted by modification/post fate. That's it. No radioactive sorting unless you clearly explained its values to the community (I suspect there are soe, but apparently consensus here that radioactive sorting is evil).

Taking into account that Scott wanted to pass multiple variables between routines, then %-named variables could serve better, making write less code. But...

To prevent variable leak outside of top-most start routine you better to New all %-named variables, e.g.

start

    new %tstVar
    set %tstVar  =  "Green"
    do TestIt()

    quit
 
TestIt() {
    write %tstVar 
}

Internally new statement creates new frame in the variables symbol table (which means virtually it's the new symbol table content), and this %-named entry will be accessible in the inner routines, even if they are of "new procedure block kind" like TestIt function here.

But, importantly, when control flow will return back to the outer start frame and quit statement will be called, it will not only return control to the proper place in caller, but it will also cleanup all new-ed variables, thus effeciantly returning back previous state of symbol table. [I do not mean it will return back variables values, I mean return back presence or absence of some variable name]

P.S.

If you know Perl then it's like local "function" work for localization scope of variables.

Rich, think about it from this prospective: Caché is inherently multiple processes system, if you need concurrency - you invoke new concurrent JOB (or submit order to the worker queue).

But there is shared memory used by whole system - this is called global buffers. If one of the processes will load some block of referenced global to the memory then it's already in shared memory, and another process will find it handily.

So, despite the percepted heavy weight of this advice but using globals as a mean for sharing data is not that bad and is pretty straightforward. Yes, for usual globals there will be extra transactions/journals mechanism involved, and if you really want to avoid them, making globals as much "in-memory" as possible then you could use ^CacheTemp* or ^mtemp globals, which will be mapped to CACHETEMP database, thus not be journalled, e.g. using ^CacheTemp.ApplicationName("pipe") for storing application data will use shared memory, will keep data in memory as long as it's used, and will not be journalled, reducing overhead to the minimum. (But please not forget to use the proper locking discipline, if you will modify this common data from several processes)

P.S.

There is close approximation for this almost in-memory mechanism which is called "process-private variables", which do use CACHETEMP mechanisms for reduced overhead, but which provides extra services with automatic cleanup of used globals once process terminated. 

But the problem is - you could not use PP variables for exchanging data with your children because they are invisible outside of this process. Unfortunately, there is no inheritance mechanism for created process-private storage when children created...

Let' start from the fact: HabraHabr practice to limit ability to edit comment to post with a couple of weeks, and edit your comment with a couple of minutes is insane. Nobody does it and it's very inconvenient.

It might make sense for high-traffic community as HabrHabr but will not make any sense here:

  • I want to be able to edit my comment while topic is vibile. At any time [though keeping editing history available, as Facebook does is a good practice];
  • And I want to be able to post new comments to any old post without any restriction.

Who knows how life will go and how old idea might become relevant in a couple of years after?

And, if this sort of question is of some interest for you, in our (originated from Russian office) projects, which we start to recommend this simple set of code guidelines - https://github.com/intersystems-ru/cos-guidelines

You may entirely ignore them, if they are incompatible with your style (and we still ok to fork your code in that case, if it's still interesting and useful), but at least pay your attention. Eventually. [Or better yet open GitHub issue if you have any complaint or suggestion]