ID |
Date |
Author |
Topic |
Subject |
1165
|
23 Feb 2016 |
Pierre-Andre Amaudruz | Forum | Problem with BLTRead | > Dear all,
>
> I'm using MIDAS system and CAEN V1721 to digitize the waveform from photomultipliers (
> and the link bridge to PC is V2718 ). I use BLTRead to read data of the digitizer, but
> I found that if the event counting rate is high ( about 100KB/s ), the communication
> of V1721 and PC would be suspended randomly, and I get an error code of -2. Could you
> give me some suggestion? Thanks a lot.
Hi,
Can you provide the BLTread call fragment code and the PC /var/log/messages at the time of
the hang up.
What is needed to restart the daq?
PAA |
1164
|
22 Feb 2016 |
ZiyiGuo | Forum | Problem with BLTRead | Dear all,
I'm using MIDAS system and CAEN V1721 to digitize the waveform from photomultipliers (
and the link bridge to PC is V2718 ). I use BLTRead to read data of the digitizer, but
I found that if the event counting rate is high ( about 100KB/s ), the communication
of V1721 and PC would be suspended randomly, and I get an error code of -2. Could you
give me some suggestion? Thanks a lot. |
1163
|
15 Feb 2016 |
Stefan Ritt | Suggestion | reducing sleep time in mhttpd main loop (for sequencer) | > Hmm, yeah, I'm not sure about how to handle reducing the wait time to zero after ODB set commands.
>
> But it does seem like it would be straight-forward to increase the sleep time for waits; I'll look into
> a clean way of doing that.
Let's see how your 10 ms work in real life. If we need variable wait times, I can implement this for your without much effort.
Stefan |
1162
|
15 Feb 2016 |
Thomas Lindner | Suggestion | reducing sleep time in mhttpd main loop (for sequencer) |
> > I checked how much extra CPU was used if the sleep was reduced from 100ms to
> > 20ms. I found that when a sequence was not running the CPU increased from 0% to
> > 0.2% with my change. When a sequence was running the CPU increased from 0.8% to
> > 4% with my change. 4% is a little high, though I'd say still reasonable. I
> > found that most of the CPU usage was occuring because every call to
> > 'sequencer()' resulted in a call to db_set_record("/Sequencer/State"...). I
> > guess that making that call 50 times causes the somewhat heavy CPU usage.
> >
> > I would argue that it would still be worth making that change, so that the
> > sequencer can be more zippy.
>
> The minimal time slice on most systems is 10 ms, and nothing prevents us from switching to
> that. The original 100 ms was more for the fact that you can see the sequencer statements
> executed one after the other (with the color bar). But this is more a "debugging" feature which
> we not really need.
OK, I made this change; sleep is now 10ms on main thread. Seems to work fine on SL6 and MacOS.
> To do it "right" the sequencer would have to _return_ a sleep time. Like if it is in a wait loop (as
> most of the time), the sleep time could be close to 1 second, to correctly update the wait
> progress bar. If the sequencer executes ODB set statements, the wait time could be zero, so
> thousands of statements can be executed in one second. The problem we will then have of course
> that the sequencer will block the "request_mutex" almost always, which would prevent the
> mongoose server from serving anything. So this should be carefully tested. It could be (on most OS)
> that releasing the mutex by the main loop immediately switches to the mongoose thread, which would
> make the web server still quite responsive, but I'm not sure about that. So as a first change making
> the sleep time 10ms should be fine.
Hmm, yeah, I'm not sure about how to handle reducing the wait time to zero after ODB set commands.
But it does seem like it would be straight-forward to increase the sleep time for waits; I'll look into
a clean way of doing that. |
1161
|
06 Feb 2016 |
Stefan Ritt | Suggestion | reducing sleep time in mhttpd main loop (for sequencer) | > There were some complaints that the MIDAS sequencer was slow. Specifically, the
> complaint was that even lines in the sequence that didn't do any (like COMMENT
> commands) tooks > 100ms to execute. These slow sequencer steps could be a
> little annoying if a script had to change a large number of ODB variables before
> starting.
>
> I tested this a little using a trivial sequence; note that I did all tests using
> mhttpd with mongoose enabled on a newer macbook pro. I found that with the
> mongoose server each line in a sequencer script was taking ~100ms. This is
> consistent with the loop in the main thread, which is only doing a cm_yield and
> a sleep:
>
> while (!_abort) {
> status = ss_mutex_wait_for(request_mutex, 0);
> status = cm_yield(0);
> if (status == RPC_SHUTDOWN)
> break;
> sequencer();
> status = ss_mutex_release(request_mutex);
> ss_sleep(100);
> }
>
> I tested reducing the sleep to 20ms. As expected, this made the sequencer more
> zippy, able to execute ~50 commands per second.
>
> I tried to think what would be downsides to making this change. I think that
> the main web communication should not be affected, because that communication is
> all handled by the separate mongoose thread.
>
> I checked how much extra CPU was used if the sleep was reduced from 100ms to
> 20ms. I found that when a sequence was not running the CPU increased from 0% to
> 0.2% with my change. When a sequence was running the CPU increased from 0.8% to
> 4% with my change. 4% is a little high, though I'd say still reasonable. I
> found that most of the CPU usage was occuring because every call to
> 'sequencer()' resulted in a call to db_set_record("/Sequencer/State"...). I
> guess that making that call 50 times causes the somewhat heavy CPU usage.
>
> I would argue that it would still be worth making that change, so that the
> sequencer can be more zippy.
The minimal time slice on most systems is 10 ms, and nothing prevents us from switching to
that. The original 100 ms was more for the fact that you can see the sequencer statements
executed one after the other (with the color bar). But this is more a "debugging" feature which
we not really need.
To do it "right" the sequencer would have to _return_ a sleep time. Like if it is in a wait loop (as
most of the time), the sleep time could be close to 1 second, to correctly update the wait
progress bar. If the sequencer executes ODB set statements, the wait time could be zero, so
thousands of statements can be executed in one second. The problem we will then have of course
that the sequencer will block the "request_mutex" almost always, which would prevent the
mongoose server from serving anything. So this should be carefully tested. It could be (on most OS)
that releasing the mutex by the main loop immediately switches to the mongoose thread, which would
make the web server still quite responsive, but I'm not sure about that. So as a first change making
the sleep time 10ms should be fine.
Stefan |
1160
|
05 Feb 2016 |
Thomas Lindner | Suggestion | reducing sleep time in mhttpd main loop (for sequencer) | > There were some complaints that the MIDAS sequencer was slow. Specifically, the
> complaint was that even lines in the sequence that didn't do any (like COMMENT
> commands) tooks > 100ms to execute. These slow sequencer steps could be a
> little annoying if a script had to change a large number of ODB variables before
> starting.
> ...
> I checked how much extra CPU was used if the sleep was reduced from 100ms to
> 20ms. I found that when a sequence was not running the CPU increased from 0% to
> 0.2% with my change. When a sequence was running the CPU increased from 0.8% to
> 4% with my change. 4% is a little high, though I'd say still reasonable. I
> found that most of the CPU usage was occuring because every call to
> 'sequencer()' resulted in a call to db_set_record("/Sequencer/State"...). I
> guess that making that call 50 times causes the somewhat heavy CPU usage.
One additional point: I think that it would be reasonably simple to reduce this CPU
usage even while a sequence was going on. I would guess that for many sequences a
lot of time was spent in a 'WAIT SECONDS' command, since you would presumably want
to wait while data was being taken or conditions stabilizing. I think that if you
are in a 'WAIT SECONDS' command that hasn't been satisfied then there probably isn't
any reason to do the db_set_record at the end of the sequencer() method. |
1159
|
05 Feb 2016 |
Thomas Lindner | Suggestion | reducing sleep time in mhttpd main loop (for sequencer) | There were some complaints that the MIDAS sequencer was slow. Specifically, the
complaint was that even lines in the sequence that didn't do any (like COMMENT
commands) tooks > 100ms to execute. These slow sequencer steps could be a
little annoying if a script had to change a large number of ODB variables before
starting.
I tested this a little using a trivial sequence; note that I did all tests using
mhttpd with mongoose enabled on a newer macbook pro. I found that with the
mongoose server each line in a sequencer script was taking ~100ms. This is
consistent with the loop in the main thread, which is only doing a cm_yield and
a sleep:
while (!_abort) {
status = ss_mutex_wait_for(request_mutex, 0);
status = cm_yield(0);
if (status == RPC_SHUTDOWN)
break;
sequencer();
status = ss_mutex_release(request_mutex);
ss_sleep(100);
}
I tested reducing the sleep to 20ms. As expected, this made the sequencer more
zippy, able to execute ~50 commands per second.
I tried to think what would be downsides to making this change. I think that
the main web communication should not be affected, because that communication is
all handled by the separate mongoose thread.
I checked how much extra CPU was used if the sleep was reduced from 100ms to
20ms. I found that when a sequence was not running the CPU increased from 0% to
0.2% with my change. When a sequence was running the CPU increased from 0.8% to
4% with my change. 4% is a little high, though I'd say still reasonable. I
found that most of the CPU usage was occuring because every call to
'sequencer()' resulted in a call to db_set_record("/Sequencer/State"...). I
guess that making that call 50 times causes the somewhat heavy CPU usage.
I would argue that it would still be worth making that change, so that the
sequencer can be more zippy. |
1158
|
28 Jan 2016 |
Amy Roberts | Suggestion | script command limited to 256 characters; remove limit? | Using low-level memory allocation routines in higher-level programs like mhttpd makes me nervous.
We could use vector arrays to allow variable-sized allocation, and use the data() member function to access the char* needed for functions like strlcat,
db_get_data, and db_sprintf.
This conforms to the c++ standard, but doesn't require explicit freeing by the user - at least, not when you're allocating std::vector<char>.
Amy
> Thank you for reporting this problem:
>
> a) ODB key *names* are restricted to 31 characters (32 bytes, last byte is a NUL), not 256 characters.
> b) ODB string length is unlimited (32-bit length field)
> c) ODB C API "db_get_value" & co require fixed length buffer and most users of this API provide a 256-byte fixed buffer for strings, some of them also do not
> check the status code, resulting in silent truncation. (I think the ODB functions themselves report truncation to midas.log, so not completely silent).
>
> We try to fix this where we must - but it is cumbersome with the current ODB API - as in your fix on has to:
> - get the ODB key, extract size
> - allocate buffer
> - call db_get_value() & co
> - use the data
> - remember to free the buffer on each and every return path
>
> The first three steps could become one if we had an ODB "get_data" function that automatically allocated the data buffer.
>
> But the main source of bugs will be the last step - remember to free the buffer, always.
>
> P.S.
>
> We are not alone in pondering how to do this best. If you want to see it "done right",
> read the fresh-off-the-presses book "Go Programming Language" by Alan Donovan and Brian Kernighan,
> http://www.gopl.io/
>
> Brian Kernighan is the "K" in K&R "C programming language", still around and kicking, now at Google.
> Sadly the "R" passed away in 2011 - http://www.nytimes.com/2011/10/14/technology/dennis-ritchie-programming-trailblazer-dies-at-70.html
>
> K.O.
>
> > Both the /Script and /CustomScript trees in the ODB allow users to trigger a
> > script via Midas - which silently truncates command strings longer than
> > 256 characters.
> >
> > I'd prefer that Midas place no limit on string length. Failing that, it would be
> > helpful to have character limits called out in the documentation
> > (https://midas.triumf.ca/MidasWiki/index.php//Script_ODB_tree#.3Cscript-name.3E_key_or_subtree,
> > https://midas.triumf.ca/MidasWiki/index.php//Customscript_ODB_tree).
> >
> > As far as I can tell, odb.c allows arbitrarily large strings in the ODB data.
> > (Although key *names* are restricted to 256 characters.) I've submitted one
> > possible version of an arbitrary-length exec_script() as a pull request
> > (https://bitbucket.org/tmidas/midas/pull-requests/).
> >
> > Am I misunderstanding any critical pieces? Does Midas intentionally treat
> > strings in the ODB as limited to 256 characters? |
1157
|
28 Jan 2016 |
Konstantin Olchanski | Suggestion | script command limited to 256 characters; remove limit? | Thank you for reporting this problem:
a) ODB key *names* are restricted to 31 characters (32 bytes, last byte is a NUL), not 256 characters.
b) ODB string length is unlimited (32-bit length field)
c) ODB C API "db_get_value" & co require fixed length buffer and most users of this API provide a 256-byte fixed buffer for strings, some of them also do not
check the status code, resulting in silent truncation. (I think the ODB functions themselves report truncation to midas.log, so not completely silent).
We try to fix this where we must - but it is cumbersome with the current ODB API - as in your fix on has to:
- get the ODB key, extract size
- allocate buffer
- call db_get_value() & co
- use the data
- remember to free the buffer on each and every return path
The first three steps could become one if we had an ODB "get_data" function that automatically allocated the data buffer.
But the main source of bugs will be the last step - remember to free the buffer, always.
P.S.
We are not alone in pondering how to do this best. If you want to see it "done right",
read the fresh-off-the-presses book "Go Programming Language" by Alan Donovan and Brian Kernighan,
http://www.gopl.io/
Brian Kernighan is the "K" in K&R "C programming language", still around and kicking, now at Google.
Sadly the "R" passed away in 2011 - http://www.nytimes.com/2011/10/14/technology/dennis-ritchie-programming-trailblazer-dies-at-70.html
K.O.
> Both the /Script and /CustomScript trees in the ODB allow users to trigger a
> script via Midas - which silently truncates command strings longer than
> 256 characters.
>
> I'd prefer that Midas place no limit on string length. Failing that, it would be
> helpful to have character limits called out in the documentation
> (https://midas.triumf.ca/MidasWiki/index.php//Script_ODB_tree#.3Cscript-name.3E_key_or_subtree,
> https://midas.triumf.ca/MidasWiki/index.php//Customscript_ODB_tree).
>
> As far as I can tell, odb.c allows arbitrarily large strings in the ODB data.
> (Although key *names* are restricted to 256 characters.) I've submitted one
> possible version of an arbitrary-length exec_script() as a pull request
> (https://bitbucket.org/tmidas/midas/pull-requests/).
>
> Am I misunderstanding any critical pieces? Does Midas intentionally treat
> strings in the ODB as limited to 256 characters? |
1156
|
28 Jan 2016 |
Konstantin Olchanski | Release | Final MIDAS JSON-RPC API | > > The final bits of the JSON-RPC API to MIDAS are committed.
JSON-RPC methods are now provided for all old ODBxxx() javascript functions, except ODBGetMsg().
The currently present RPC methods are sufficient to write the MIDAS "programs" and "alarms" pages
purely in HTML+Javascript (see the git branch feature/mhttpd_js). These pages can be served i.e. by apache httpd
with midas mhttpd only required to service the RPC requests.
Please see .../examples/javascript1/example.html on how to use the new RPC methods.
K.O.
P.S. Note how many examples use the generic mjsonrpc_call() because I did not write the corresponding
javascript functions - I wore out the cut-and-paste button on my keyboard. All are welcome to contribute
the missing functions, post them here or email them to me, I will commit them to midas git. |
1155
|
19 Jan 2016 |
Tom Stuttard | Suggestion | 64 bit bank type | > > I've seen that a similar question has been asked in 2011 but I'll ask again in
> > case there are any updates. Is there any way to write 64-bit data words to MIDAS
> > banks (other than breaking them up in to two 32-bit words, such as 2 DWORDs)
> > currently? And if not, is there any plan to introduce this feature in the future?
>
> There is no "breaking them up" as such, you can treat a midas bank as a char* array
> and store arbitrary data inside. In this sense, "there is no need" for a special 64-bit bank type.
>
> For endian-ness conversion (if such things still matter, big-endian PPC CPUs still exist), single 64-bit
> word converts the same as two 32-bit words, so here also "there is no need", once can use banks of
> DWORD with equal effect.
>
> The above applies equally to 64-bit integers and 64-bit double-precision IEEE-754 floating point
> numbers.
>
> But specifically for 64-bit values, such as float64, there is a big gotcha.
>
> The MIDAS banks structure goes to great lengths to make sure each data type is correctly aligned,
> and gets it exactly wrong for 64-bit quantities - all because the bank header is three 32-bit words.
>
> bankhheader1
> bh2
> bh3
> bankdata1 <--- misaligned
> ...
> bankdataN
> bh1
> bh2
> bh3
> banddata1 <--- aligned
> ... etc
>
> So we could introduce QWORD banks today, but inside the midas file, they will be misaligned defeating
> the only purpose of adding them.
>
> I guess the misalignement could be cured by adding dummy words, dummy banks, dummy bank
> headers, etc.
>
> I figure this problem dates all the way bank where alignement to 16-bits was just getting important.
> Today, in the VME word, I have to align things on 128-bit boundaries (for 2eSST 2x2 DWORD transfers).
>
> So back to your question, what advantage do you see in using a QWORD bank instead of putting the
> same data in a DWORD bank?
>
> K.O.
Thanks very much for your reply. I have implemented your suggestion of treating the 64-bit array as a 32-bit
array for the bank write/read and this solution is working for me.
Thanks again for your help. |
Draft
|
15 Jan 2016 |
Tom Stuttard | Suggestion | 64 bit bank type | > > I've seen that a similar question has been asked in 2011 but I'll ask again in
> > case there are any updates. Is there any way to write 64-bit data words to MIDAS
> > banks (other than breaking them up in to two 32-bit words, such as 2 DWORDs)
> > currently? And if not, is there any plan to introduce this feature in the future?
>
> There is no "breaking them up" as such, you can treat a midas bank as a char* array
> and store arbitrary data inside. In this sense, "there is no need" for a special 64-bit bank type.
>
> For endian-ness conversion (if such things still matter, big-endian PPC CPUs still exist), single 64-bit
> word converts the same as two 32-bit words, so here also "there is no need", once can use banks of
> DWORD with equal effect.
>
> The above applies equally to 64-bit integers and 64-bit double-precision IEEE-754 floating point
> numbers.
>
> But specifically for 64-bit values, such as float64, there is a big gotcha.
>
> The MIDAS banks structure goes to great lengths to make sure each data type is correctly aligned,
> and gets it exactly wrong for 64-bit quantities - all because the bank header is three 32-bit words.
>
> bankhheader1
> bh2
> bh3
> bankdata1 <--- misaligned
> ...
> bankdataN
> bh1
> bh2
> bh3
> banddata1 <--- aligned
> ... etc
>
> So we could introduce QWORD banks today, but inside the midas file, they will be misaligned defeating
> the only purpose of adding them.
>
> I guess the misalignement could be cured by adding dummy words, dummy banks, dummy bank
> headers, etc.
>
> I figure this problem dates all the way bank where alignement to 16-bits was just getting important.
> Today, in the VME word, I have to align things on 128-bit boundaries (for 2eSST 2x2 DWORD transfers).
>
> So back to your question, what advantage do you see in using a QWORD bank instead of putting the
> same data in a DWORD bank?
>
> K.O. |
1153
|
05 Jan 2016 |
Konstantin Olchanski | Suggestion | 64 bit bank type | > I've seen that a similar question has been asked in 2011 but I'll ask again in
> case there are any updates. Is there any way to write 64-bit data words to MIDAS
> banks (other than breaking them up in to two 32-bit words, such as 2 DWORDs)
> currently? And if not, is there any plan to introduce this feature in the future?
There is no "breaking them up" as such, you can treat a midas bank as a char* array
and store arbitrary data inside. In this sense, "there is no need" for a special 64-bit bank type.
For endian-ness conversion (if such things still matter, big-endian PPC CPUs still exist), single 64-bit
word converts the same as two 32-bit words, so here also "there is no need", once can use banks of
DWORD with equal effect.
The above applies equally to 64-bit integers and 64-bit double-precision IEEE-754 floating point
numbers.
But specifically for 64-bit values, such as float64, there is a big gotcha.
The MIDAS banks structure goes to great lengths to make sure each data type is correctly aligned,
and gets it exactly wrong for 64-bit quantities - all because the bank header is three 32-bit words.
bankhheader1
bh2
bh3
bankdata1 <--- misaligned
...
bankdataN
bh1
bh2
bh3
banddata1 <--- aligned
... etc
So we could introduce QWORD banks today, but inside the midas file, they will be misaligned defeating
the only purpose of adding them.
I guess the misalignement could be cured by adding dummy words, dummy banks, dummy bank
headers, etc.
I figure this problem dates all the way bank where alignement to 16-bits was just getting important.
Today, in the VME word, I have to align things on 128-bit boundaries (for 2eSST 2x2 DWORD transfers).
So back to your question, what advantage do you see in using a QWORD bank instead of putting the
same data in a DWORD bank?
K.O. |
1152
|
05 Jan 2016 |
Tom Stuttard | Suggestion | 64 bit bank type | I've seen that a similar question has been asked in 2011 but I'll ask again in
case there are any updates. Is there any way to write 64-bit data words to MIDAS
banks (other than breaking them up in to two 32-bit words, such as 2 DWORDs)
currently? And if not, is there any plan to introduce this feature in the future?
Many thanks,
Tom |
1151
|
10 Dec 2015 |
Stefan Ritt | Info | Small change in loading .odb files | A small change in loading .odb files has been implemented. When you load an array from a .odb file, the indices in each line were not evaluated, only the complete array was loaded. In our experiment we need however to load only a few values, like some HV values for some channels but leaving the other values as they are. I changed slightly the code of db_paste() to correctly evaluate the index in each line of the .odb file. This way one can write for example following .odb file:
[/Equipment/HV/Variables]
Demand = FLOAT[256] :
[10] 100.1
[11] 100.2
[12] 100.3
[13] 100.4
[14] 100.5
[15] 100.6
then load it in odbedit via the "load" command, and then only change channels 10-15.
Stefan |
1150
|
10 Dec 2015 |
Amy Roberts | Suggestion | script command limited to 256 characters; remove limit? | Both the /Script and /CustomScript trees in the ODB allow users to trigger a
script via Midas - which silently truncates command strings longer than
256 characters.
I'd prefer that Midas place no limit on string length. Failing that, it would be
helpful to have character limits called out in the documentation
(https://midas.triumf.ca/MidasWiki/index.php//Script_ODB_tree#.3Cscript-name.3E_key_or_subtree,
https://midas.triumf.ca/MidasWiki/index.php//Customscript_ODB_tree).
As far as I can tell, odb.c allows arbitrarily large strings in the ODB data.
(Although key *names* are restricted to 256 characters.) I've submitted one
possible version of an arbitrary-length exec_script() as a pull request
(https://bitbucket.org/tmidas/midas/pull-requests/).
Am I misunderstanding any critical pieces? Does Midas intentionally treat
strings in the ODB as limited to 256 characters? |
1149
|
02 Dec 2015 |
Konstantin Olchanski | Release | Final MIDAS JSON-RPC API | > The final bits of the JSON-RPC API to MIDAS are committed.
Here is example conversion of the function "generate midas message" from old-style AJAX to JSON-RPC:
before (mhttpd.cxx):
/* process "jgenmsg" command */
if (equal_ustring(getparam("cmd"), "jgenmsg")) {
if (getparam("facility") && *getparam("facility"))
strlcpy(facility, getparam("facility"), sizeof(facility));
else
strlcpy(facility, "midas", sizeof(facility));
if (getparam("user") && *getparam("user"))
strlcpy(user, getparam("user"), sizeof(user));
else
strlcpy(user, "javascript_commands", sizeof(user));
if (getparam("type") && *getparam("type"))
type = atoi(getparam("type"));
else
type = MT_INFO;
if (getparam("msg") && *getparam("msg")) {
cm_msg1(type, __FILE__, __LINE__, facility, user, "%s", getparam("msg"));
}
show_text_header();
rsputs("Message successfully created\n");
return;
}
after: (mjsonrpc.cxx)
static MJsonNode* js_cm_msg1(const MJsonNode* params)
{
if (!params) {
MJSO *doc = MJSO::I();
doc->D("Generate a midas message using cm_msg1()");
doc->P("facility?", MJSON_STRING, "message facility, default is \"midas\"");
doc->P("user?", MJSON_STRING, "message user, default is \"javascript_commands\"");
doc->P("type?", MJSON_INT, "message type, MT_xxx from midas.h, default is MT_INFO");
doc->P("message", MJSON_STRING, "message text");
doc->R("status", MJSON_INT, "return status of cm_msg1()");
return doc;
}
MJsonNode* error = NULL;
const char* facility = mjsonrpc_get_param(params, "facility", &error)->GetString().c_str();
const char* user = mjsonrpc_get_param(params, "user", &error)->GetString().c_str();
int type = mjsonrpc_get_param(params, "type", &error)->GetInt();
const char* message = mjsonrpc_get_param(params, "message", &error)->GetString().c_str(); if (error) return error;
if (strlen(facility)<1)
facility = "midas";
if (strlen(user)<1)
user = "javascript_commands";
if (type == 0)
type = MT_INFO;
int status = cm_msg1(type, __FILE__, __LINE__, facility, user, "%s", message);
return mjsonrpc_make_result("status", MJsonNode::MakeInt(status));
}
With the corresponding javascript-side stabs:
before:
function ODBGenerateMsg(type,facility,user,msg)
{
var request = XMLHttpRequestGeneric();
var url = ODBUrlBase + '?cmd=jgenmsg';
url += '&type='+type;
url += '&facility='+facility;
url += '&user='+user;
url += '&msg=' + encodeURIComponent(msg);
request.open('GET', url, false);
request.send(null);
return request.responseText;
}
after:
function mjsonrpc_cm_msg(message, type, id) {
/// \ingroup mjsonrpc_js
/// Get values of ODB variables
///
/// RPC method: "cm_msg1"
///
/// \code
/// mjsonrpc_cm_msg("this is a new message").then(function(rpc) {
/// var req = rpc.request; // reference to the rpc request
/// var id = rpc.id; // rpc response id (should be same as req.id)
/// var status = rpc.result.status; // return status of MIDAS cm_msg1()
/// ...
/// }).catch(function(error) {
/// mjsonrpc_error_alert(error);
/// });
/// \endcode
/// @param[in] message Text of midas message (string)
/// @param[in] type optional message type, one of MT_xxx. Default is MT_INFO (integer)
/// @param[in] id optional request id (see JSON-RPC specs) (object)
/// @returns new Promise
///
var req = new Object();
req.message = message;
if (type)
req.type = type;
return mjsonrpc_call("cm_msg1", req, id);
}
K.O |
1148
|
30 Nov 2015 |
Konstantin Olchanski | Release | Final MIDAS JSON-RPC API | The final bits of the JSON-RPC API to MIDAS are committed. The API uses the Javascript Promise mechanism (supported on all
supported platforms - MacOS, Windows, Linux Ubuntu, el5, el6, el7).
Simple example for pasting the current run number into an html element:
mjsonrpc_db_get_values(["/runinfo/run number"]).then(function(rpc) {
document.getElementById("run_number").innerHTML = rpc.response.data[0];
}).catch(function(error) {
mjsonrpc_error_alert(error);
});
The documentation for the JSON-RPC API, including special quirks in JSON encoding of ODB data is here:
https://midas.triumf.ca/MidasWiki/index.php/Mjsonrpc
Documentation (with examples) for the related Javascript functions in mhttpd.js is here (via Doxygen):
https://daq.triumf.ca/~daqweb/doc/midas-devel/html/group__mjsonrpc__js.html
Examples of using all mhttpd.js functions is in .../examples/javascript1/example.html
The experimental git branch feature/mhttpd_js implements the MIDAS "programs" page purely in html and javascript,
go there to see all this new JSON and RPC stuff in action. See .../resources/programs.html.
K.O. |
1147
|
27 Nov 2015 |
Konstantin Olchanski | Info | updated: note on midas history | (update: resolve all FIXMEs, document the breakup of "structured banks")
This note documents the workings of the midas history.
There is 2 separate history sections: equipment history and links history.
* is equipment history enabled?
For each equipment, history is controlled by the value of /eq/xxx/common/period:
0 = history disabled
1 = history is enabled
>1 = history is enabled, throttled down
The throttling is implemented in log_history()/watch_history() by this algorithm:
the very first history event is recorded, then all changed to the data are ignored until
"period" seconds has elapsed. Then the next history event will be recorded, and following
changes will be ignored until "period" second elapses, and so forth. Period value "1" has
special meaning - there is no throttling, all history events are logged.
If equipment history is enabled, history events are created by parsing the content of /eq/xxx/variables.
* what is history events?
A "history event" is a history atomic unit of data. Associated with each history event is a timestamp (unix time),
a name (limited to NAME_LENGTH in the old history) and a list of history tags that describe the individual data
values inside the history event.
When making history plots in mhttpd, for each curve on the plot, one selects a history event (from the list
of currently active events, recently active events or the list of all events that ever existed), then from the list of tags
inside the history event one selects the particular variable that will be plotted.
In the old MIDAS history, all history events are written into one history file (.hst file + optional .def and .idx event definition and time index files
which can be/are regenerated automatically from the .hst file). History events are identified by 16-bit history event IDs, the persistent mapping
from history event names and the 16-bit history event IDs is stored in ODB /History/Events. In addition the list of all known history event tags is
stored in ODB /History/Tags. For per-equipment history, the 16-bit history event ID is the value of ODB "/eq/xxx/common/event id".
In the SQL history (MySQL, SQLITE, etc), each history event is an SQL table. The history event tags are the SQL table columns.
In the new FILE history, each history event is written into a separate file, tag definition are recorded in text formal in the file header, history event
data is appended to the file in binary format (fixed record size). If the history event definition is changed, a new file will be started.
* how are history events constructed?
The mlogger creates history events in open_history() by parsing ODB /eq/xxx/variables. Each ODB entry under "variables" is referred to as a "variable".
Each variable can be a single ODB value, an array of ODB values, or a subdirectory (corresponding to TID_STRUCT structured data banks). As each variable
is processed, one or more tags are created to describe it. Single ODB values will generally produce a single tag, while arrays can produce
one single tag - describing the whole array - or multiple tags - one per array element - depending whether the array is "named" or not.
The code can generate two types of history:
- "per-equipment" history will have the tags for all variables concatenated together into one single history event
- "per-variable" history will have one history event defined for each variable. Inside could be one tag - for single odb values and unnamed arrays - or multiple tags - for named arrays and structured data
banks.
Per-equipment history is the original MIDAS history implementation.
Per-variable history was added to permit efficient data storage in SQL tables. It's initial implementation used 1 ODB hotlink for each variable and it was easy to exceed the maximum permitted number of
ODB hotlinks (db_open_record()).
To reduce consumption of hotlinks, db_watch() has been implemented and now per-variable history only uses 1 ODB hotlink per equipment.
With db_watch, per-equipment history is no longer available. per-variable history is the new default (and the only option).
* how are the history event tags constructed?
(quirk - single odb values are treated as arrays of length "1")
FIXME: single odb values should be treated as such, /eq/xxx/settings/names should not be applied
(quirk - "string" ODB entries are not permitted)
FIXME - single odb values of type TID_STRING should be possible with SQL, FILE and MIDAS history. arrays of strings is impossible "struct TAG" does not have a data field for string length - only n_data and
item length implied through it's TID.
History event tags are constructed in the mlogger add_equipment().
For variables of type TID_KEY (subdirectories, corresponding to TID_STRUCT structured banks), one tag is generated for each subdirectory entry. Tag names for /eq/xxx/var/aaa/bbb will be "aaa_bbb".
(with an underscore).
FIXME: subdirectory entries of type TID_KEY and TID_LINK should be explicitly forbidden.
FIXME: TID_KEY could be supported by replacing db_get_data() with db_get_record() in watch_history().
FIXME: TID_LINK could be supported by adding db_watch() on the link target.
For named arrays, individual tags are generated for each array element. Tag names are taken from the names array. For empty tag names (empty names array), tags are "aaa_0", "aaa_1", etc (for
/eq/xxx/var/aaa). For "single names" arrays, tag names have the variable name appended (with a space), for /eq/xxx/var/aaa and an empty names array, tags will be "aaa_0 aaa", "aaa_1 aaa", etc. For
populated names array, the tags will be "name0 aaa", "name1 aaa", etc.
For unnamed arrays and single odb variables (in ODB, single odb variables are arrays of length 1), a single tag is generated.
For TID_LINK variables what happens? FIXME!
FIXME: support TID_LINK variables by correctly parsing the link target and setting a db_watch() on the link target.
Named arrays have a "Names" entry in /eq/xxx/settings. For example, to add names to /eq/xxx/var/aaa, create a string array "/eq/xxx/settings/names aaa". The names array should be at least as long as
the corresponding data array. Individual entries in the names array can be left blank (tag names will be "aaa_0", "aaa_1", etc). Duplicate tag names are not permitted.
A single "Names" entry can be created to name all arrays in variables with the same names ("single names"). Create /eq/xxx/settings/names" and arrays /eq/xxx/var/aaa and /eq/xxx/var/bbb will have
history tags "name0 aaa", "name1 aaa", "name0 bbb", "name1 bbb", etc. If "names" are left blank, tag names will be "aaa_0 aaa", "aaa_1 aaa", "bbb_0 bbb", "bbb_1 bbb", etc.
In the mhttpd variables viewer, "single name" arrays are displayed in a 2D table.
* /history/links history
History events are created for each entry under /history/links.
Two types of links are permitted:
/history/links/aaa is a link to a subdirectory: db_watch() is setup to watch this subdirectory, tags are created for each subdirectory entry (1 tag per entry). There is no possibility for naming array elements, so 1 tag per array, regardless of the number of elements.
/history/links/bbb is a subdirectory with links to odb values: db_watch is setup to watch each link target, tags are created for each link (1 tag per link). tag name is the link name (NOT the target name). There is no possibility for naming array elements.
FIXME: Mixing links and subdirectories is not permitted, but could be done - additional db_watch() will need to be done on any links.
Update period history events created for /history/links is controlled by entries in "/history/links periods". Numeric values of periods are same as for equipment histories. Numeric value 0 disables the history for a particular event.
K.O. |
1146
|
27 Nov 2015 |
Konstantin Olchanski | Info | synchronous ajax deprecated | > > I checked again on browser compatibility:
> >
> > el6: firefox 38 - ok, google-chrome 27 - no
>
> It looks like this does mean that people using RHEL6 won't have the option of chrome - can they update chrome?
>
It turns out that google-chrome 38 is available for RHEL6/SL6 via an old chromium build. Promises are supported (passes my tests).
See here:
http://www.if-not-true-then-false.com/2013/install-chromium-on-centos-red-hat-rhel
This is where I got the working chromium 38 (no explanation of why there are no newer builds)
http://people.centos.org/hughesjr/chromium/6/x86_64/RPMS/
There appear to be newer builds here: (but I will not test them)
http://install.linux.ncsu.edu/pub/yum/itecs/public/chromium-dev/rhel6/x86_64/
My SL6 google-chrome and chromium instructions:
https://www.triumf.info/wiki/DAQwiki/index.php/SLinstall#Install_Google_Chrome_web_browser_.2864-bit_SL6.29
K.O. |
|