Skip to content

Conversation

@davidbuckley123
Copy link

@davidbuckley123 davidbuckley123 commented Apr 29, 2024

It looks like we'll have to use a sync response.
Dashboards are config'd to send down a negative handle, but the wrapper that the dashboards add looks like the below:

"({[f;w;r;x;u].dash.u:u;res:.[f;(w;r;x);{[w;r;e]neg[.z.w](`.dash.snd_err;w;r;e)}[w;r]];.dash.u:`;res};{[o;w;r;x]neg[.z.w](`.dash.rcv_msg;w;o;r;x[0] sublist value x 1)}[2];7i;904i;(2000i;\".kxdash.dashexec[\\\"select first time from trade\\\";`rdb`hdb;raze]\");`default)"

The x[0] sublist value x 1 always gives a (::) result on async methods. This causes dashboards to recognise no result has been returned. Due to this, I have converted to sync.

Additionally, TorQ has a condition checking for negative handles vs sync/async. I have had to add a condition to ignore this if .kxdash.enabled is set to 1b.

As below, this is tested and working through the front-end.
image

image

@davidbuckley123
Copy link
Author

FYI @jonnypress

.gw.asyncexecjpt now only returning 1 result (not 1 from each hdb)
@davidbuckley123
Copy link
Author

davidbuckley123 commented Apr 30, 2024

Debugging .gw.asyncexecjpt double return
Before
image

// from a remote q process, hitting the gateway, 
q).z.ps:{0N!x;value x}
q)gw:hopen`::17007:rdb:pass
q)neg[gw]".gw.asyncexecjpt[\".proc.procname\";`hdb`rdb;raze;();0Wn]";gw[]
`hdb1`rdb1
q)`hdb2`rdb1 // where does this come from????
q)[gw]".gw.syncexecj[\".proc.procname\";`hdb`rdb;raze]"
`hdb1`rdb1


// attempting again with .kxdash.enabled:0b
q)gw:hopen`::17007:rdb:pass
q)neg[gw]".gw.asyncexecjpt[\".proc.procname\";`hdb`rdb;raze;();0Wn]";gw[]
`hdb1`rdb1
q)[gw]".gw.syncexecj[\".proc.procname\";`hdb`rdb;raze]"
`hdb1`rdb1
q)
// Looks better…



// Seems like this is coming from the below from kxdash.q
Line 58  //.dotz.set[`.z.ps;{x@y;.kxdash.dashps y}@[value;.dotz.getcommand[`.z.ps];{{value x}}]];
// attempting to write a new version of .kxdash.dashps




//Dashboard query for testing
neg[gw]"value({[f;w;r;x;u].dash.u:u;res:.[f;(w;r;x);{[w;r;e]neg[.z.w](`.dash.snd_err;w;r;e)}[w;r]];.dash.u:`;res};{[o;w;r;x]neg[.z.w](`.dash.rcv_msg;w;o;r;x[0] sublist value x 1)}[2];7i;904i;(2000i;\".kxdash.dashexec[\\\"select first time from trade\\\";`rdb`hdb;raze]\");`default)";gw[]


// testing looks good
q)neg[gw]"value({[f;w;r;x;u].dash.u:u;res:.[f;(w;r;x);{[w;r;e]neg[.z.w](`.dash.snd_err;w;r;e)}[w;r]];.dash.u:`;res};{[o;w;r;x]neg[.z.w](`.dash.rcv_msg;w;o;r;x[0] sublist value x 1)}[2];7i;904i;(2000i;\".kxdash.dashexec[\\\"select first time from trade\\\";`rdb`hdb;raze]\");`default)";gw[]
`.dash.rcv_msg
7i
2
904i
+(,`time)!,2024.04.29D00:00:00.537034586 2024.04.01D00:00:03.838217000

After
image

@davidbuckley123
Copy link
Author

Additionally, the sublist'ing segment is still in place

// against rdb
q)neg[gw]"value({[f;w;r;x;u].dash.u:u;res:.[f;(w;r;x);{[w;r;e]neg[.z.w](`.dash.snd_err;w;r;e)}[w;r]];.dash.u:`;res};{[o;w;r;x]neg[.z.w](`.dash.rcv_msg;w;o;r;x[0] sublist value x 1)}[2];7i;904i;(2000i;\".kxdash.dashexec[\\\"select from trade\\\";`rdb;raze]\");`default)";rh:gw[]
q)rh
`.dash.rcv_msg
7i
2
904i
+`time`sym`price`size`stop`cond`ex`side!(2024.04.29D00:00:00.537034586 2024.0..
q)count last rh
2000
// against rdb and hdb
q)neg[gw]"value({[f;w;r;x;u].dash.u:u;res:.[f;(w;r;x);{[w;r;e]neg[.z.w](`.dash.snd_err;w;r;e)}[w;r]];.dash.u:`;res};{[o;w;r;x]neg[.z.w](`.dash.rcv_msg;w;o;r;x[0] sublist value x 1)}[2];7i;904i;(2000i;\".kxdash.dashexec[\\\"select from trade\\\";`rdb`hdb;raze]\");`default)";rh:gw[]
q)count last rh
2000

// Reset format response
.gw.formatresponse:formatresponse;
// incorporate dashps into the .z.ps definition
.dotz.set[`.z.ps;{x@y;.kxdash.dashps y}@[value;.dotz.getcommand[`.z.ps];{{value x}}]];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.kxdash.dashps is executed after the original .z.ps definition - are we actually using dashparams anywhere after this change? or the dashremote and dashjoin functions? Seems like most of this script is possibly redundant if we're just using the original .z.ps?

syncexecjpre36:{[query;servertype;joinfunction]
// Check correct function called
if[(.z.w<>0)&(.z.w in key .gw.call)&not .gw.call .z.w;
if[(.z.w<>0)&(.z.w in key .gw.call)&(not .gw.call .z.w)& not @[value;`.kxdash.enabled;0b];
Copy link
Member

@jonathonmcmurray jonathonmcmurray May 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will allow syncexec to be called via async request as long as .kxdash.enabled is true i.e. it'd allow a non-kx dashboard client to send async request to syncexec, which I don't think is what we want?

it also seems strange to me that we are using syncexecjpre36 for async requests from kx dashboards, is this definitely the correct approach? (I guess this is because kx dashboards is essentially doing a defferred sync request with it's own wrapper, so it's simpler on our side to treat it as a sync request, so this probably does make sense)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidbuckley123 couple of points to pick up here if you get a chance

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-kx dashboard client to send async request to syncexec
Fair enough - the if[] statement could be tightened up a bit.

I am only trying to enabled syncexec calls from a negative handle from kx dashboards.
Honestly, I am not 100% satisfied with this as a solution.
I'll take some time and see if I can come up with something more elegant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants