- Log in to post comments
Hi @Guillaume Rongier !
Thank you!
Yes, I continue working on this project after writing this article.
I have to write a sequel.
You can see a summary of the activity on this dashboard :
And the detail for a CSP\REST here:
- Log in to post comments
Hello @Michael Davidovich ,
Did you try to override OnPreDispatch ?
Also you can configure your web application to use a subclass of %CSP.SessionEvents and override OnStartRequest, OnEndRequest .
Set Application = "/csp/YourWebApp"
Do ##class(Security.Applications).Get(Application, .p)
Set p("EventClass") = "YourCSPEventsClassName"
Set sc = ##class(Security.Applications).Modify(Application, .p)- Log in to post comments
- Log in to post comments
Wonderful!
- Log in to post comments
Well done! Don't worry about your brain 😉
; 67 bytes improvement by Julius Kavay
1 s c=$a(s,$i(i)) q:c<0 '$g(z) g:c=41-c+40 1 q:$i(z,c-40.5)>0 0 g 1- Log in to post comments
Variant 69 bytes:
ClassMethod IsValid(s As %String) As %Boolean
{
1 s c=$a(s,$i(i)) q:c<0 '$g(z) g:"()"'[$c(c) 1 q:$i(z,c-40.5)>0 0 g 1
}- Log in to post comments
Another solution, 82 bytes:
/// ( -> -0.5
/// ) -> 0.5
ClassMethod IsValid(s As %String) As %Boolean
{
s z=0,s=$zstrip(s,"*E",,"()") f s c=$a(s,$i(i)) ret:c<0 'z ret:$i(z,c-40.5)>0 0
}- Log in to post comments
Hello @Sukhpreet Singh,
You can use the global mapping in "%ALL" namespace.
This is the most convenient way.
- Log in to post comments
Hello @Nildo Torres ,
If the collation to install is identified, you can use the following classmethod :
Set $Namespace = "%SYS"
; Change fraw by the locale you need.
Set sc = ##class(Config.NLS.Locales).Install("fraw")- Log in to post comments
Finally, I found the solution :
$SYSTEM.OBJ.IsUpToDate("classname")- Log in to post comments
Finally, there is a trick!
Thank you @Guillaume Rongier !
I share this with our dev interoperability team.
- Log in to post comments
Hello @Benjamin De Boe ,
It's great news that the performance is improved for the tune table. Given the volume of data on some installations, a tune table could take more than 15 days.
I hope to see a significant decrease now that we are migrating our installations to IRIS.
However, I have a few comments on the current workings.
SQL Stats are in the code, which makes it very difficult to manage.
If a table has no statistics, when the first query is run, the table tune is executed. This is great!
However, since it is automatic and the statistics are stored in the class definition, when a developer creates a record in the table and runs a test, it will generate the stats and it will certainly end up in the repository. We lose the benefit of the automatic execution of the tuning, but even worse we have unrepresentative statistics.
Another problem: Even if we import the statistics after the deployment of a new version, if we update a class (bug fix), we have to remember to import the corresponding statistics.
All this requires particular vigilance. I hope that in a future version, there will be a split between the stats and the code. We can't really commit stats in our application repository because, from one installation to another, the stats can be different depending on how the application is used.
I am thinking of developing a tool to manage SQL statistics:
- Comparison of production statistics with recalculated statistics on a test server (with a copy of the data).
- Manual selectivity management for the rare cases where the tune table would not be efficient (to avoid overwriting manually modified values).
- Identification of statistics that need to be modified in production (due to ratio change, value distribution).
I am working on an application that contains far too many tables to be able to do this work manually.
It's great to have improved the performance of the tune table as well as the documentation (I read it yesterday and it's much clearer) and I hope you will improve the system with the split stats\code.
Thank you!
- Log in to post comments
I agree with @Pietro Montorfano , due to the type of failure it's not possible to know the stop reason.
Also, If it's an abnormal stop the execution of ZSTOP is not guaranteed.
Depending on your target, maybe you can execute code on start (ZSTART routine) to clean something when the system has been stopped abnormally. It could be identified by a trace in your application database or a scan of the messages.log
- Log in to post comments
Thanks you for this tips @Bob Kuszewski
Maybe the following line allows to retrieve, but I don't have Windows Docker environment to test myself:
Set ip = $SYSTEM.INetInfo.HostNameToAddr("host.docker.internal")@Robert Cemper : If you test this line with Docker for Windows, let me know if It works or not.
Thank you.
- Log in to post comments
Hi @Robert Cemper ,
I already do this with an environment variable passed in the docker-compose file. I don't know if smarter solution exists.
- Log in to post comments
Hi @Iryna Mykhailova!
Thank you. This is an interesting example for the community!
I have often used this when I need to expose data in SQL only stored in globals (without related class definition).
I like the possibility of using the stored procedure "as a table":
ClassMethod ShowData()
{
Set rset = ##class(%SQL.Statement).%ExecDirect(,"SELECT * FROM Sample.Human_GetAllOlderThan(?)",65)
Do rset.%Display()
}We can further filter the results with a where clause without changing the code of the custom class query.
- Log in to post comments
Hi @Scott Roth ,
Ten years ago, I implement %ZSTOP routine to execute code when a job process exits or when the instance shutdown. I removed my code, but the routine looks like this:
%ZSTOP ; User shutdown routine.
Quit
SYSTEM ; Cache stopping
Set oldNs = $Namespace
Try {
Set $Namespace = "MYAPPNAMESPACE"
; Do something when stopping the instance.
}Catch(ex) {}
Set $Namespace = oldNS
Quit
LOGIN ; a user logs out of Cache (user account or telnet)
Quit
JOB ; JOB'd process exits.
If $Namespace = "MYAPPNAMESPACE" {
; do something when job process exits
}
Quit
CALLIN ; process exits via CALLIN interface.
Quit
Logit(entrypoint, caller) PRIVATE ;
Quit- Log in to post comments
Hello @Kurt Hofman ,
I experienced a similar problem the last week while testing a library.
To solve it, I created the PYTHONPATH system environment variable with C:\InterSystems\IRISHealth\lib\python\Lib\site-packages\win32;C:\InterSystems\IRISHealth\lib\python\Lib\site-packages\win32\lib.
IRIS need to be restarted to consider any change in an environment variable.
Check If pythoncom39.dll and pywintypes39.dll exist in the directory C:\InterSystems\IRISHealth\lib\python\Lib\site-packages\win32. If they don't exist, copy them. I don't remember the initial directory of these dll files (maybe C:\InterSystems\IRISHealth\mgr\python\pywin32_system32).
I'm a beginner in Python, so maybe a more simple and clean solution exists...
Hope this help.
- Log in to post comments
Hi @Scott Roth ,
The routine ZMIRROR.MAC must be installed in the namespace "%SYS" on each failover member. It needs the IRISLIB database mounted in RW for installation.
I use ZMIRROR.MAC to execute code when a node becomes primary, in my example I just implement "NotifyBecomePrimary" label :
ZMIRROR
Quit
NotifyBecomePrimary()
New
; https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GHA_mirror#GHA_mirror_set_tunable_params_zmirror_routine
Try {
Set ns = "MYAPPNAMESPACE"
If ##class(Config.Namespaces).Exists(ns) {
JOB ##class(pkg.Class).ClassMethod():(ns):2
}
} Catch(ex) { } ; just a security
Quit:$Quit 1
QuitThere are many events available, we can see the list on this documentation page .
What event mirror are you interested in?
- Log in to post comments
Exactly @Tani Frankel !
Thank you for this refresh
- Log in to post comments
I think the created resource id is in the header response. I don't remember the header name 🤔
- Log in to post comments
Hello @Pietro Montorfano ,
You can try to write your own export method.
Using %Library.RoutineIndex looks good. Example to export all ".MAC" :
set tRes = ##class(%SQL.Statement).%ExecDirect(.tStmt,"select name||'.'||type as itemName from %Library.RoutineIndex where type = ? and $Extract(name,1) <> '%'","MAC")
While tRes.%Next() {
Do $SYSTEM.OBJ.ExportUDL(tRes.%Get("itemName"),"<dir>/"_tRes.%Get("itemName"))
}- Log in to post comments
For adding a member, this is the IP of the first member (primary). It's correct.
No matter the virtual IP, it's the role of the arbiter\agent to communicate who is primary in case of a switch.
However, a virtual IP is convenient for access to your applications.
For example, with web applications: If the system switches from node A to node B, it is more convenient to use a virtual IP address. You can use this in your web server configuration so that it always points to the primary node.
- Log in to post comments
Hi @Scott Roth ,
I have to search the documentation, but I remember we don't use the virtual IP to set up a mirror member.
The DR member knows who is the primary throughout the arbiter\agent.
- Log in to post comments
Hi,
This would be an elegant solution rather than adding code to the "ValidateObject" method!
- Log in to post comments
Change done.
Let me know if the problem persists.
- Log in to post comments
Indeed !
The copy paste from google drive create links to my google account ...
Thank you for this report I modify that asap.
- Log in to post comments
Congratulations to all!
It was a fantastic contest!
This is the first time I have seen so many applications.
- Log in to post comments
