As a first step, I would check file/directory owner + protection in WINDOWS related to Studio Windows user
< DIRECTORY> is not so specific on the reasons
- Log in to post comments
As a first step, I would check file/directory owner + protection in WINDOWS related to Studio Windows user
< DIRECTORY> is not so specific on the reasons
If you look at GitHub, you find a kind of CSS there
http://https://github.com/intersystems-community/webterminal/tree/master/src/client/scss
They might be present somewhere in your installation.
You may play with it at your own risk
again YES !
Any expansion is related to an extension of the internal mapping structure of the .DAT file
written to disk If you don't have any restrictions on disk space, you consume the related
overhead in 1 single shot at a time that you control (e.g., startup)
HMMM.
Are you sure that WS and WSS Protocol are enabled on the Webserver
https://ac1.mqtt.sx3ac.com
And any firewall in between?
In short:
Assuming you have full access to your Windows you may take this approach.
You are right, The example defines
Class WSCI.CRE Extends (%RegisteredObject, %Net.WebSocket.ICredentials)
but doesn't use it,
According to the class definition of %Net.WebSocket.Client you pass it as a parameter
in the %New() method..png)
so you code (extending my example may look like this:
set cre=##class(WSCI.CRE).%New()
#; feed whatever your credentials need
#; init connection
set ws=##class(%Net.WebSocket.Client).%New(url,cre,evl)It might be worth checking what class %Net.WebSocket.Client does with your credentials
The article https://community.intersystems.com/post/websocket-client-iris-internal
has a link to OEX https://openexchange.intersystems.com/package/IRIS-internal-WebSocket-Client
which points to code on Github that includes a Client and an Echo Server for testing
the code runs on any IRIS. Docker is just a helping platform
It would be great to get all the code from Github be published on OpenExchange
Dmitry, you are just great.
And you impressed me over and over again.
Thank you for sharing your knowledge and your passion
About 5 years back, I composed an example for a WebSockel Client
might be a starting point
Point 2. of the previous reply is definitely WRONG!
Point 4. takes that back in some way but leaves it ambiguous.
Using extended Global References (also in Class Storage Definitions)
allows access to any mounted DB if you have access rights.
A personal example:
USER>for i=1:1:5 set ^|"^^C:\InterSystems\IRIS242\mgr\nonspace"|rcc(i)=i
USER>zwrite ^|"^^C:\InterSystems\IRIS242\mgr\nonspace"|rcc
^|"^^C:\InterSystems\IRIS242\mgr\nonspace"|rcc(1)=1
^|"^^C:\InterSystems\IRIS242\mgr\nonspace"|rcc(2)=2
^|"^^C:\InterSystems\IRIS242\mgr\nonspace"|rcc(3)=3
^|"^^C:\InterSystems\IRIS242\mgr\nonspace"|rcc(4)=4
^|"^^C:\InterSystems\IRIS242\mgr\nonspace"|rcc(5)=5
USER>I learned this traditional technique 47 years ago.
And it still works fine.
straight ObjectScript
USER>if $d(^|"%SYS"|CONFIG("Namespaces"," ")) ;; position $ZR in CONFIG
USER>for set ns=$o(@$ZR) quit:ns="" zwrite ns ; list it
ns="%SYS"
ns="SAMPLES"
ns="USER"
USER>BINGO !
What about "InterSystems ObjectScript" ?
>>> short ISOS ?? 😉
An excellent experience !
thanks for sharing.
Fully agree with your suggestion of an Abstract Class.
It's in fact the modern equivalent of the old .INC approach
much more simple with 2 identic .INT routines a1 and a2
ROUTINE a1 [Type=INC]
load ;
read !,"loops=",loop,!
do t1 hang 0.5 do t2 quit
next
set t1=$zh quit
t1
set t0=$zh
for i=1:1:loop do next
write t1-t0,!
quit
t2
set t0=$zh
for i=1:1:loop do next^a2
write t1-t0,!
quit
SAMPLES>d ^a1
loops=1000000
.081626
.136785
SAMPLES>I just mean you can't do less:
the difference is even worse 40.3%
My approach was rather simple.
SUMMARY: There is a difference.
But I wouldn't bend a little finger to attack it. (not even on PDP-11)
This is nothing where performance comes from.
OK - in UDL
IRIS for Windows (x86-64) 2024.3 (Build 217U) Thu Nov 14 2024 17:59:58 EST
ROUTINE anna [Type=INC] anna(name) quit ""
A.HUGE.cls
Include anna
Class A.HUGE Extends (%Persistent, %Populate)
{
Property calc As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ];
ClassMethod fill(size) As %String [ SqlProc ]
{
for i=1:1:size set ^A.HUGED(i)=""
set ^A.HUGED=i
quit $ZR_"="_@$ZR
}
ClassMethod test1(val) As %String [ SqlProc ]
{
quit ##class(A.PERSON).Anna(val)
}
ClassMethod test2(val) As %String [ SqlProc ]
{
quit $$anna(val)
}
Storage Default
{
<Data name="HUGEDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
</Data>
<DataLocation>^A.HUGED</DataLocation>
<DefaultData>HUGEDefaultData</DefaultData>
<IdLocation>^A.HUGED</IdLocation>
<IndexLocation>^A.HUGEI</IndexLocation>
<StreamLocation>^A.HUGES</StreamLocation>
<Type>%Storage.Persistent</Type>
}
}A.PERSON.cls
Include anna
Class A.PERSON Extends %Persistent
{
Property calc As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ];
ClassMethod fill(size) As %String [ SqlProc ]
{
for i=1:1:size set ^A.PERSOND(i)=""
set ^A.PERSOND=i
quit $ZR_"="_@$ZR
}
ClassMethod test1(val) As %String [ SqlProc ]
{
quit ##class(A.PERSON).Anna(val)
}
ClassMethod Anna(name As %String) As %String
{
quit $$anna(name)
}
Storage Default
{
<Data name="PERSONDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
</Data>
<DataLocation>^A.PERSOND</DataLocation>
<DefaultData>PERSONDefaultData</DefaultData>
<IdLocation>^A.PERSOND</IdLocation>
<IndexLocation>^A.PERSONI</IndexLocation>
<StreamLocation>^A.PERSONS</StreamLocation>
<Type>%Storage.Persistent</Type>
} }I did this to verify my approach looping over a simulated table of 100 mio rows
The difference is evident:
[SQL]SAMPLES>>select A.HUGE_fill(100000000) 18. select A.HUGE_fill(100000000) | Expression_1 | | -- | | ^A.HUGED=100000000 | 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0008s/5/828/0ms execute time(s)/globals/cmds/disk: 18.8332s/100,000,002/200,000,445/0ms query class: %sqlcq.SAMPLES.cls3 --------------------------------------------------------------------------- [SQL]SAMPLES>>select list(A.HUGE_TEST1(ID)) from A.HUGE 19. select list(A.HUGE_TEST1(ID)) from A.HUGE | Aggregate_1 | | -- | | | 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0005s/4/141/0ms execute time(s)/globals/cmds/disk: 101.5573s/100,000,001/700,000,424/0ms query class: %sqlcq.SAMPLES.cls2 --------------------------------------------------------------------------- [SQL]SAMPLES>>select list(A.HUGE_TEST2(ID)) from A.HUGE 20. select list(A.HUGE_TEST2(ID)) from A.HUGE | Aggregate_1 | | -- | | | 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0005s/4/141/0ms execute time(s)/globals/cmds/disk: 72.1640s/100,000,001/700,000,424/0ms query class: %sqlcq.SAMPLES.cls1 --------------------------------------------------------------------------- [SQL]SAMPLES>>
Rough calculation: including the code in the class saves ~30% of execution time
my class code
Include anna
Class A.HUGE Extends (%Persistent, %Populate)
{
Property calc As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ];
ClassMethod fill(size) As %String [ SqlProc ]
{
for i=1:1:size set ^A.HUGED(i)=""
set ^A.HUGED=i
quit $ZR_"="_@$ZR
}
ClassMethod test1(val) As %String [ SqlProc ]
{
quit ##class(A.PERSON).Anna(val)
}
ClassMethod test2(val) As %String [ SqlProc ]
{
quit $$anna(val)
}The simplified anna,INC just returns NullString to concentrate on code switching
anna(name)
quit ""Loading compiled obj code from cache to partition should not have any remarkable impact.
But you are right by principle ! It's some kind of overhead and not for free.
If you place the affected code into a .INC routine you may share that piece
rather easy over multiple instances.
Though mostly not used in that way any Include may also contain executable code.
For a :MAC routine it's nothing impressive.
For Class code it's a bit tricky but works as well
example ANNA.INC
anna(name) ;
write !,"Hello ",name,!
quit ">>>"_name_"<<<"example Anna.CLS
/// demo for Anna
Include ANNA
Class A.Anna {
ClassMethod demo(name As %String) As %String
{
quit $$anna(name)
}
}It works:
SAMPLES>write "===",##class(A.Anna).demo("robert")
===
Hello robert
>>>robert<<<
SAMPLES>So multiple loading is reduced.
You have of course also the option to compose a Custom Command in %ZLANG***.MAC
I just have no experience of how this impacts partition loading.
The generated .INT proves it.png)
Studio shows the Error already during typing..png)
But this works fine as you expected:.png)
BINGO !
.png)
composed by nI
Exactly.!
..#PARAMETER inserts a STRING
But >>> $NAME() looks for a variable also by indirection
USER>w $name("^rcc(1)")
W $NAME("^rcc(1)")
^
<SYNTAX>
USER>w $name(^rcc(1))
^rcc(1)
USER>s x="^rcc(1)"
USER>w $name(x)
x
USER>w $name(@x)
^rcc(1)
USER>OOOOOPS 😮
Hi Jean,
at first glance I'd expect the query plan for #18. and #19. should be quite similar
:SQL offers 3 levels to see the query plan
This might offer a chance to identify the difference.
There's still an - unlikely - chance that #19 runs on some broken cached query,
that never was updated. so clear cached queries might be a possible solution. Not an explanation
Best regards, Robert
Interoperability is not available in all namespaces.
Typically not in %SYS, but in USER
Check in Management Portal. where it is included.
I'm once more impressed by your contribution.
As often in past you leave the (mostly boring) mainstream,
look over the mental fence and bring tools and solutions
beyond the usual compositions that I see repeatedly in my reviews.
this is just great! . 👏 👍
Hello community;