大家好!欢迎参加InterSystems第21届开发者大赛!
🏆 InterSystems 2022 Full Stack开发者大赛 🏆
时间: 2022年6月27日-7月17日(美东时间)
奖金:$10,000
大家好!欢迎参加InterSystems第21届开发者大赛!
🏆 InterSystems 2022 Full Stack开发者大赛 🏆
时间: 2022年6月27日-7月17日(美东时间)
奖金:$10,000
%XML.XPATH.Document中CreateFromFile方法,
如:
可根据此思想进行多任务启动查询汇总数据。
job机制开启后台进程。loop循环减少进程的数量等于开启进程的数量,判断多进程任务是否完成。创建表并插入1000W条数据,统计Moeny字段总金额
创建demo代码如下。
Class Demo.SemaphoreDemo Extends %RegisteredObject
{
/// Do ##class(Demo.SemaphoreDemo).Sample(5)
ClassMethod Sample(pJobCount = 3)
{
k ^yx("Amt"),^yxAmt
/* 1.启动信号 */
s mSem = ##class(Demo.Sem).%New()
If ('($isobject(mSem)))
{
q "启动失败"
}
/* 2. 初始化信号量为0 */
d mSem.Init(0)
s t1 = $zh
/* 3. 按指定数量,启动后台任务 */
for i = 1 : 1 : pJobCount
{
j .Cache数据库使用M语言如何调用第三方视图呢,有没有对应使用文档呢?
Main、Producer 和 Consumer 这三个类中的每一个都有自己的 Run 方法,最好在各自的终端窗口中运行它们。每次运行时,它都会显示它为日志生成的消息。一旦用户通过提供它正在等待的输入来响应 Main 类,Main 的 Run 方法将终止删除信号量。然后,用户可以通过键入命令查看所有进程的合并日志文件的显示
Do ##class(Semaphore.Util).ShowLog()
注意:以下所有示例都假定所有类都已在“USER”命名空间中编译。
最简单的例子演示了信号量的创建和销毁。它使用 Semaphore.Main 类。请执行下列操作:
Do ##class(Semaphore.Main).Run()
Enter 键。该方法显示信号量的初始化值,将其删除,然后退出。Do ##class(Semaphore.Util).ShowLog()
按照上述步骤在终端窗口中显示的消息示例如下
消息示例如下
DHC-APP>Do ##class(Semaphore.Main).下面是一系列使用信号量实现生产者/消费者场景的类。 “主”进程初始化信号量并等待用户指示活动已全部完成。生产者在循环中随机增加一个信号量值,更新之间的延迟可变。消费者尝试在随机时间从信号量中删除随机数量,也是在循环中。该示例由 5 个类组成:
Main – 初始化环境并等待信号量上的活动完成的类。Counter – 实现信号量本身的类。它记录它的创建以及由于信号量在等待列表中而发生的任何回调。Producer – 一个类,其主要方法增加信号量值。增量是一个随机选择的小整数。完成增量后,该方法会在下一个增量之前延迟一小段随机数秒。Consumer 消费者——这是对生产者的补充。此类的主要方法尝试将信号量减少一个随机选择的小整数。它将递减请求添加到其等待列表中,等待时间也是随机选择的秒数。注意:组成这些类的代码特意写得简单。尽可能地,每个语句只完成一个动作。这应该使用户更容易和更直接地修改示例。
此类建立演示环境。它调用实用程序类来初始化日志和名称索引工具。
Globals,这些存储数据的魔剑,已经存在了一段时间,但是没有多少人能够有效地使用它们,也没有多少人知道这个超级武器。
如果你把Globals的东西用在它们真正能发挥作用的地方,其结果可能是惊人的,要么是性能的提高,要么是整体解决方案的大幅简化 (1, 2).
Globals提供了一种特殊的存储和处理数据的方式,它与SQL表完全不同。它们在1966年首次出现在 M(UMPS)编程语言中, 该语言最初用于医学数据库。现在它仍然以同样的方式被使用,但也被其他一些以可靠性和高性能为首要任务的行业所采用:金融、交易等。
后来M(UMPS)演变为 Caché ObjectScript (COS). COS是由InterSystems公司开发的,作为M的一个超集. 其原始语言仍然被开发者社区所接受,并在一些实现中保持活力。在网络上有几个活跃的网址,比如:MUMPS Google group, Mumps User's group), effective ISO Standard等等
现代基于Globals的数据库支持交易、日志、复制、分区等。这意味着它们可以被用来构建现代的、可靠的、快速的分布式系统。
Gloabls并不将你限制于关系模型的范围内。它们让你可以自由地创建为特定任务优化的数据结构。对于许多应用来说,合理地使用好的Globals就如一颗真正的银子弹头,它所提供的速度是传统关系型应用的开发者所梦寐以求的。
作为一种存储数据的方法,globals可以在许多现代编程语言中使用,包括高级和低级语言。因此,本文将特别关注Globals本身,而不是它们曾经来自的语言。
比较不同的商业智能技术是非常有趣的。我很好奇它们在功能、开发工具、速度和可用性方面有什么不同。
在这个应用程序中,我选择了一个有欧洲各国水状况的数据集。这是一个开源的数据集,包含1991年到2017年的观测数据。
团队和我决定使用IRIS BI、Tableau、PowerBI和InterSystems Reports(由Logi Reports驱动)在这个BI数据集的基础上制作一个模型
对于前端,我们通过Embedded Python在PythonFlask中制作了一个网页界面。
顺便说一下,其结果可以在这个网页上看到:http://atscale.teccod.com:8080/
你可以看看demo stand (演示台),因为从资源库部署一个容器可能需要多至20分钟的时间。大量的python包,后面会有更多的原因。
主页面
事实上,数据似乎很小,期间只有17年 :)
因此,在现有的基础上,我想延续数据集,为此使用了一个神经网络。使用同样的嵌入式Python,使用了Tensorflow,这个包下载后占据了511MB,不要惊讶
实际上,这也是容器部署时间长的原因--为神经网络下载了很多包,相当多的相关包,安装时间很长。不过会有一篇关于神经网络和Integrated ML(一体化机器学习)的单独文章,我很快会发表。
我还要说的是,预测的结果被输入到同一个数据库,所以你可以通过BI工具看到数据集。
维基百科对信号量有这样的定义:“在计算机科学中,特别是在操作系统中,信号量是一种变量或抽象数据类型,用于控制多个进程在并行编程或多用户环境中对公共资源的访问。”信号量不同于互斥体(或锁)。互斥锁最常用于管理竞争进程对单个资源的访问。当一个资源有多个相同的副本并且这些副本中的每一个都可以由单独的进程同时使用时,就会使用信号量。
考虑一个办公用品商店。它可能有几台复印机供其客户使用,但每台复印机一次只能由一个客户使用。为了控制这一点,有一组键可以启用机器并记录使用情况。当客户想要复印文件时,他们向职员索取钥匙,使用机器,然后归还钥匙,并支付使用费。如果所有机器都在使用,客户必须等到钥匙归还。保存键的位置用作信号量。
该示例可以进一步推广到包括不同类型的复印机,也许可以通过它们可以制作的副本的大小来区分。在这种情况下,将有多个信号量,如果复制者在复制的大小上有任何重叠,那么希望复制共同大小的客户将有两个资源可供提取。
信号量是共享对象,用于在进程之间提供快速、高效的通信。每个信号量都是类 %SYSTEM.Semaphore 的一个实例。信号量可以建模为一个共享变量,它包含一个 64 位非负整数。信号量上的操作在共享它的所有进程中以同步的方式更改变量的值。按照惯例,值的变化会在共享信号量的进程之间传递信息。
在前一篇文章中,我已经演示了一种简单的方法来记录数据的变化。在这个时候,我改变了负责记录审计数据的 "审计抽象类 "和记录审计日志的数据结构。
我已经将数据结构改为父子结构,其中将有两个表来记录 "交易 "和在该交易中改变的 "字段的值"。
看一下新的数据模型:

看看从 "审计类 "改变的代码吧:
下面的代码允许用户查看其实例的审计设置。通过运行类方法 "test "来运行该代码。:
class objectscript.checkAudit Extends %RegisteredObject
{
classmethod test() {
w "Checking for Auditing.",!
Set SYSOBJ = ##class(Security.System).%OpenId("SYSTEM")
If +SYSOBJ = 0 Set SYSOBJ = ##class(Security.System).%New()
i SYSOBJ.AuditEnabled {
w "Security Auditing is enabled for the following services",!
s rs=##class(%ResultSet).%New("Security.Events:ListAllSystem")
s sc=rs.Execute() If $$$ISERR(sc) Do DisplayError^%apiOBJ(sc) Quit
while rs.%Next() {
d:rs.在这篇文章中,我将解释如何通过使用CSP Web应用程序以及启用/禁用和认证/取消认证任何Web应用程序的代码来进行认证、授权和审计。
应用层
注:IRIS有,Cache无。
^LOGDMN 例程允许管理结构化日志记录;还有一个基于类的 API,将在下一节中介绍。
要使用 ^LOGDMN 启用结构化日志记录:
set $namespace="%sys"
do ^LOGDMN
这将启动一个带有以下提示的例程:
1) Enable logging
2) Disable logging
3) Display configuration
4) Edit configuration
5) Set default configuration
6) Display logging status
7) Start logging
8) Stop logging
9) Restart logging
LOGDMN option?
4 以便可以指定配置详细信息。然后,该例程会提示输入以下项目:a. 最低日志级别,以下之一:
-2 — 详细的调试消息(例如十六进制转储)。-1 — 不太详细的调试消息。0 — 信息性消息,包括所有审计事件。1(默认值)— 警告,表示可能需要注意但未中断操作的问题。2 — 严重错误,表明问题已中断操作。3 — 致命错误,表示问题导致系统无法运行。b. 管道命令,它指定系统将结构化日志发送到哪里。
IRIS 支持结构化日志记录。
创建多个日志,每个日志用于不同的目的。从以前的产品迁移过来的客户可以像过去一样利用这些日志,但现在还可以将所有日志信息导入一个单一的、中央的、机器可读的日志文件——结构化日志。然后可以将此文件与第三方分析工具一起使用。
本文概述了结构化日志中的信息,展示了日志示例,并描述了如何启用结构化日志记录。
当启用结构化日志记录时,系统会将相同的数据写入结构化日志,它也会写入其他日志(无论哪个)。例如,系统将相同的行写入messages.log 和结构化日志。
启用结构化日志记录后,结构化日志包含以下所有信息:
messages.log 的信息。这包括需要注意的警报、有关系统启动和关闭的信息、有关日志文件和 WIJ 文件的高级信息、有关配置更改 (CPF) 的信息以及与许可相关的信息。本部分显示结构化日志记录实用程序的示例输出,用于名称/值对格式和 JSON 格式。
以下输出使用格式选项 NVP(名称/值对)。此示例经过编辑以用于显示目的;在实际输出中,每个条目只占一行,条目之间没有空行。
when="2019-08-01 18:43:02.216" pid=8240 level=SEVERE event=Utility.要创建一个存储为整数的新位串,请对每个位求和 2 的幂:
set bitint = (2**2) + (2**5) + (2**10)
write bitint
1060
要将现有位串中的位设置为 1,请使用 $zboolean 函数(逻辑 OR)的选项7 (arg1 ! arg2):
set bitint = $zboolean(bitint, 2**4, 7)
write bitint
1076
要将现有位串中的位设置为 0,请使用 $zboolean 函数的选项 2 (arg1 & ~arg2):
set bitint = $zboolean(bitint, 2**4, 2)
write bitint
1060
要在现有位串中切换位,请使用 $zboolean 函数(逻辑 XOR)的选项 6 (arg1 ^ arg2):
set bitint = $zboolean(bitint, 2**4, 6)
write bitint
1076
set bitint = $zboolean(bitint, 2**4, 6)
write bitint
1060
要将位字符串显示为整数,可以使用如下方法,该方法循环位并使用 $zboolean 函数:
Class Util.嗨,开发者们!欢迎加入第二届InterSystems技术写作大赛!
6月20日至七月20日 延长至7月31日,在社区撰写一篇利用InterSystems技术使用Python的文章,主题自定。
🎁 撰文即得奖 我们为每一位参与此次写作大赛的作者准备了一份特殊礼品!
🏆 优秀文章大奖 AirPods Max; Apple Watch SE; Apple HomePod mini / Apple Pencil
InterSystems许可证是指InterSystems发放的电子或纸质版的产品许可证,内容包括许可证订购日期、产品描述等。
激活码/License Key是InterSystems随许可证发放的许可软件激活码。通常情况下,客户收到的是电子许可证。
以下是一些许可证,激活码/License key常见咨询问题参考:
纸质版许可证或是安装介质盘,可通过合作伙伴或是致电原厂核验许可证信息后获取。
申请准备:
WRC全球响应中心联络信息:
要创建新的位串,请使用 $bit 函数将所需位设置为 1:
kill bitstring
set $bit(bitstring, 3) = 1
set $bit(bitstring, 6) = 1
set $bit(bitstring, 11) = 1
使用 $bit 将现有位串中的位设置为 1:
set $bit(bitstring, 5) = 1
使用 $bit 将现有位串中的位设置为 0:
set $bit(bitstring, 5) = 0
由于位串中的第一位是位 1,因此尝试设置位 0 会返回错误:
set $bit(bitstring, 0) = 1
SET $BIT(bitstring, 0) = 1
^
<VALUE OUT OF RANGE>
要测试是否在现有位串中设置了位,还可以使用 $bit 函数:
write $bit(bitstring, 6)
1
write $bit(bitstring, 5)
0
如果测试未明确设置的位,则 $bit 返回 0:
write $bit(bitstring, 4)
0
write $bit(bitstring, 55)
0
要显示位串中的位,请使用 $bitcount 函数获取位串中位的计数,然后遍历位:
forHi 社区,
这是海外工程师做的一个纯浏览器的代码编辑器CloudStudio. 欢迎大家下载试用:
GitHub 下载:
https://github.com/SeanConnelly/CloudStudio
InterSystems 应用市场下载:https://openexchange.intersystems.com/package/CloudStudio
到Discord 讨论区:https://discord.gg/ZnvdMywsjP
Docker 支持与在线Demo:
已安装 git 和 Docker desktop .
Clone/git 把 repo 导入任何本地目录
git https://github.com/rcemper/Dataset-OEX-reviews.git
启动IRIS容器:
docker-compose up -d --build
http://localhost:42773/cloudstudio/CloudStudio.Index.cls
Demo 视频:https://www.youtube.com/watch?v=Am6QAvrPPPg
如果要将一系列布尔参数传递给方法,一种常见的方法是将它们作为编码为单个整数的位序列传递。
例如,Security.System.ExportAll() 方法用于从 IRIS 实例中导出安全设置。如果查看此方法的类引用,将看到它的定义如下:
classmethod ExportAll(FileName As %String = "SecurityExport.xml",
ByRef NumExported As %String, Flags As %Integer = -1) as %Status
第三个参数 Flags 是一个整数,其中每个位代表一种可以导出的安全记录。
如果您使用InterSystems技术开发了自己的网络应用,现在想在客户端进行验证码验证,以确定用户真实性使其更加安全。有一些现代框架可以解决验证码的问题,然而它们中的大多数需要互联网接入来生成代码,有时实施起来很复杂。考虑到图像识别已经非常成熟,您可以参考本文为基本例子。这就是为什么现在倾向于看到更多的模式识别验证码而不是单纯的阅读验证码。(例如,点击所有有店面的图片)。如果你需要更复杂的东西,请继续开发,改进这个代码并分享它。 继续阅读以了解如何使用这个基本的例子:
Demo.Captcha class
使用这个类,你可以在一个物理目录上创建验证码图像文件,以便在你的应用程序上显示。请注意,创建图像的目录必须是可用的,以便你的Web应用程序访问这些图像。要创建验证码图像,请调用以下方法,将完整的文件名作为一个参数:
创建 image 文件
InterSystems正在招聘Market Development Representative欢迎您的自荐、推荐。
InterSystems正在招聘Technical Specialist(Implementation),欢迎您的自荐、推荐。
InterSystems正在招聘Technical Specialist(Product Support),欢迎您的自荐、推荐。
我们正在招聘Support Facilitator,欢迎您的自荐、推荐。
有时可能希望在基于数据平台的应用程序中存储一系列相关的布尔值。可以创建许多布尔变量,也可以将它们存储在数组或列表中。或者可以使用称为“位串”的概念,它可以定义为位序列,首先呈现最低有效位。位串允许您以非常有效的方式存储此类数据,无论是在存储空间还是处理速度方面。
位串可以以两种方式之一存储,作为压缩字符串或整数。如果在没有上下文的情况下听到术语“位串”,则表示位序列存储为压缩字符串。本文向介绍了这两种类型的位串,然后介绍了一些可用于操作它们的技术。
存储位序列的最常见方式是在位串中,这是一种特殊的压缩字符串。除了节省存储空间外,还可以使用 ObjectScript 系统函数有效地操作位串。
这样的系统函数是 $factor,它将整数转换为位串。我们可以通过执行以下语句将整数 11744 转换为位串:
set bitstring = $factor(11744)
要查看位串内容的表示,可以使用 zwrite 命令:
zwrite bitstring
bitstring=$zwc(128,4)_$c(224,45,0,0)/*$bit(6..9,11,12,14)*/
起初它看起来很神秘,但在输出的末尾,会看到一条注释,其中显示了已设置的实际位的列表:6、7、8、9、11、12 和 14。位串中的位 1表示 2^0,位 2 表示 2^1,依此类推
为了将自动故障转移扩展到尽可能广泛的故障情况,InterSystems建议你为每个镜像配置一个仲裁机。
要充当仲裁者,系统必须有一个正在运行的ISCAgent进程。由于ISCAgent是与InterSystems IRIS一起安装的,任何承载一个或多个InterSystems IRIS实例的系统都符合这一要求,可以被配置为仲裁者而无需进一步准备;但是,承载一个或多个故障转移或DR异步镜像成员的系统不应该被配置为该镜像的仲裁者。
没有托管InterSystems IRIS实例的系统可以通过安装Arbiter方式的作为仲裁者。请从InterSystems公司下载适合你的仲裁者系统平台的ISCAgent安装包,然后,安装ISCAgent。
注意:Arbiter的版本要和InterSystems IRIS安装版本保持一致。
在Windows系统上,只需执行安装文件,例如ISCAgent-2020.1.0.540.0-win_x64.exe。
[root@arbiterhost home]# gunzip ISCAgent-2020.1.0.540.0-lnxrhx64.tar.gz
[root@arbiterhost home]# tar -xf ISCAgent-2020.1.0.540.增量锁定具有潜在危险,因为它可能导致称为死锁的情况。当两个进程各自对已被另一个进程锁定的变量断言增量锁定时,就会出现这种情况。因为尝试的锁是增量的,所以现有的锁不会被释放。结果,每个进程在等待另一个进程释放现有锁的同时挂起。
举个例子:
A 发出此命令:lock + ^MyGlobal(15)B 发出此命令:lock + ^MyOtherGlobal(15)A 发出此命令:lock + ^MyOtherGlobal(15)此 LOCK 命令不返回;进程被阻塞,直到进程 B 释放这个锁。
B 发出此命令:lock + ^MyGlobal(15)此 LOCK 命令不返回;进程被阻塞,直到进程 A 释放这个锁。但是,进程 A 被阻塞,无法释放锁。现在这些进程都在等待对方。
有几种方法可以防止死锁:
timeout 参数。LOCK 命令的顺序,请遵循严格的协议。只要所有进程都遵循相同的锁名称顺序,就不会发生死锁。一个简单的协议是按排序顺序添加锁。+ 运算符。如前所述,对于简单锁定,LOCK 命令首先释放进程持有的所有先前锁定。 (然而,在实践中,简单的锁定并不经常使用。使用升级锁来管理大量锁。当锁定数组的节点时,它们是相关的,特别是当将多个节点锁定在同一下标级别时。
当给定进程在同一数组中的给定下标级别创建了超过特定数量(默认为 1000)的升级锁时, 将删除所有单独的锁名称并用新锁替换它们。新锁位于父级,这意味着数组的整个分支被隐式锁定。示例(如下所示)演示了这一点。
应用程序应在合适的情况下尽快释放特定子节点的锁(与非升级锁完全相同)。当释放锁时, 会减少相应的锁计数。当的应用程序移除足够多的锁时,会移除父节点上的锁。第二小节显示了一个示例。
假设有 1000 个^MyGlobal("sales","EU",salesdate) 形式的锁,其中 salesdate 表示日期。锁表可能如下所示:
注意 Owner 19776 的条目(这是拥有锁的进程)。 ModeCount 列指示这些是共享的、升级的锁。
当同一进程试图创建另一个相同形式的锁时, 会升级它们。它会移除这些锁并用名称为 ^MyGlobal("sales","EU") 的单个锁替换它们。现在锁表可能如下所示:
ModeCount 列表明这是一个共享的升级锁,它的计数是 1001。
请注意以下关键点:
^MyGlobal("sales","EU") 的所有子节点现在都被隐式锁定,遵循数组锁定的基本规则。如上所述,如果您将 timeout 指定为 0, 会添加锁。但是,如果使用零超时锁定父节点,并且已经在子节点上锁定,则忽略零超时并使用内部 1 秒超时。
要删除默认类型的锁,请使用 LOCK 命令,如下所示:
LOCK -lockname
如果执行此命令的进程拥有具有给定名称的锁(默认类型),则此命令将删除该锁。或者,如果进程拥有多个锁(默认类型),此命令将删除其中一个。
或者删除另一种类型的锁:
LOCK -lockname#locktype
其中 locktype 是一串锁类型代码。
LOCK 命令的其他基本变体为了完整起见,本节讨论 LOCK 命令的其他基本变体:使用它来创建简单的锁并使用它来删除所有锁。这些变化在实践中并不常见。
对于 LOCK 命令,如果省略 + 运算符,LOCK 命令首先会删除该进程持有的所有现有锁,然后尝试添加新锁。在这种情况下,锁称为简单锁而不是增量锁。一个进程可以拥有多个简单的锁,如果该进程使用如下语法同时创建它们:
LOCK (^MyVar1,^MyVar2,^MyVar3)
简单的锁在实践中并不常见,因为通常需要持有多个锁并在代码的不同步骤中获取它们。因此使用增量锁更实用。
但是,如果简单锁适合,请注意,可以在创建简单锁时指定 locktype 和 timeout 参数。