gpt4 book ai didi

coldfusion - Lucee/Adobe ColdFusion - 从线程设置/获取信息{}

转载 作者:行者123 更新时间:2023-12-02 01:54:09 28 4
gpt4 key购买 nike

我正在创建一个简单的电子邮件服务器状态页面,该页面调用两个不同的 CFC。

状态页面要求:

  1. 通过 CFC 查询 MariaDB 数据库表并从两个字段返回数据:server_name(即 MyServerName)和 server_domain(即 mail.domain.com)。目前,数据库表中有 4 行需要提取。
  2. 将步骤 1 中的数据库数据传递给 CFC,检查端口 25 是否正在监听。如果 CFC 可以到达端口 25,则结果为 true,否则结果为 false。此步骤需要线程化。
  3. 通过循环传递步骤 2 中的 bool 结果以打印 server_name 和 bool 结果。

输出类似的内容:
我的服务器名称 - <up arrow>
我的服务器名称2 - <up arrow>
我的服务器名称3 - <up arrow>
我的服务器名称4 - <down arrow>

代码:

    RetrieveEmailServers = APPLICATION.selectQueries.RetrieveEmailServers()
if (RetrieveEmailServers.recordCount) {
for(i = 1; i <= RetrieveEmailServers.recordCount(); i++) {
LOCAL.theDomains = RetrieveEmailServers.check_servers_domain[i];
LOCAL.theNames = RetrieveEmailServers.check_servers_name[i];
thread action="run" name="thread#i#" theDomains="#LOCAL.theDomains#" theNames="#LOCAL.theNames#" {
VARIABLES.theServers = APPLICATION.emailCheck.checkSMTPServer('#domains#',25,'','');
}
}
thread action="join" timeout="6000"{}

for(i = 1; i <= RetrieveEmailServers.recordCount(); i++) {
VARIABLES.theResult = cfthread["thread#i#"];
if (VARIABLES.theResult.theServers) {
LOCAL.theStatus = "<i class='fad fa-angle-double-up text-success fs-1'></i>"
}
else {
LOCAL.theStatus = "<i class='fad fa-angle-double-down text-danger fs-1'></i>"
}
writeOutput(ATTRIBUTES.theNames & " - " & LOCAL.theStatus & "<br>");
}
}
else {
writeOutput("No servers listed at this time.")
}

错误:键[THESERVERS]不存在,结构为空

供考虑:

  1. 我知道我的代码不是很好,而且我知道它可以写得更好。我正在努力提高。
  2. 我不是一名全职编码员,但我已经断断续续地编码了很多次年。我仍然认为自己是 CFML 的新手,所以很多方法都超出了我的理解。
  3. 上面的代码大部分都能工作,但我很难理解如何在 CFTHREAD 之外传递信息以供其余部分使用页面的大小,尤其是在处理 CFLOOP 时。
  4. 读了很多遍,还是不太明白,怎么办正确使用线程局部作用域、线程作用域和属性范围。
  5. 上面的代码有一个简单的任务,检查端口,但最终目标是对我的应用程序的其他部分使用类似的代码。我知道有更好的监控工具可用;这是一个帮助我理解和学习的练习。
  6. 具体到 Lucee,我知道 threadData()['thread#i#'].status;或类似的可能需要对 cfthread[] 进行修改.

最佳答案

属性

Attributes范围仅用于保存传递到线程的值。因此,作用域是短暂的,仅存在于线程内。每个线程都有自己的“属性”范围,该范围在该线程运行之前或完成之后不存在。

例如,此代码片段传入名为“theDomains”的属性。变量Attributes.theDomains仅存在于线程内部

 thread action="run" name="thread1" theDomains="example.com" {
writeDump( attributes.theDomains );
}

thread action="join" name="thread1" {};

writeOutput( thread1.output );

线程本地

“Thread-local”是另一个短暂的作用域,其目的是保存在线程内使用的变量。每个线程都有自己的私有(private)“本地”范围,与所有其他线程分开。喜欢attributes作用域,它仅在线程执行时存在,并在线程完成时被清除。

例如,此代码片段创建一个名为“MyLocalVar”的局部变量。显示线程output表明变量存在于线程内

thread action="run" name="thread1" {
// Un-scoped v
myLocalVar = "foo";
writeOutput( "myLocalVar ="& myLocalVar );
}

thread action="join" name="thread1" {};
writeOutput( thread1.output );

但是在线程完成后尝试访问它会导致错误

// fails with error "key [MYLOCALVAR] doesn't exist"
writeOutput( "myLocalVar ="& thread1.myLocalVar );

Thread范围

Thread范围的使用生命周期更长。它旨在存储 "..thread-specific variables and metadata about the thread..." 。更重要的是,该作用域可用于将信息传递回调用页面(甚至其他线程)。

例如,此代码片段创建一个线程作用域变量,即使在线程完成执行之后,该变量对调用页面也是可见的:

 thread action="run" name="thread1" {
// use scope prefix "thread."
thread.myThreadVar = "foo";
}

thread action="join" name="thread1" {};

writeOutput( "thread1.myThreadVar="& thread1.myThreadVar );
writeDump( thread1 );

问题:键 [THESERVERS] 不存在

当您花了几天时间查看错误时,很容易忘记基础知识:) 处理未定义错误的第一件事是转储对象并查看是否实际上包含什么内容您在尝试使用它之前所期望的。

for(i = 1; i <= RetrieveEmailServers.recordCount(); i++) {
VARIABLES.theResult = cfthread["thread#i#"];
writeDump( variables.theResult );

/* temporarily comment out rest of code
...
*/
}

VARIABLES.theResult 的转储显示线程实际上因不同的错误而失败

CFDump of Thread 1

由于线程内的属性名称错误。应该是attributes.theDomains ,不是domains .

thread ...{
APPLICATION.emailCheck.checkSMTPServer( attributes.theDomains, ... );
}

好的,我修好了。仍然收到“ key [THESERVERS] 不存在”,现在怎么办?

另一个线程转储显示该错误消息并非谎言。这些线程确实不包含名为 theServers 的变量,由于范围界定不正确。使用thread范围,而不是“变量”。

 thread ...{
thread.theServers = ....;
}

CFDump of Thread 2

又一个错误?!变量 [ATTRIBUTES] 不存在

即使解决了前两个问题,您仍然会在这里收到另一个错误

for(i = 1; i <= RetrieveEmailServers.recordCount(); i++) {
...
writeOutput(ATTRIBUTES.theNames & " - " & LOCAL.theStatus & "<br>");
}

记住attributes作用域仅存在于线程内。所以显然一旦线程完成就不能使用它。任一商店theNamesthread范围也如此,或者由于您正在循环查询,因此请使用查询列值 RetrieveEmailServers.the_query_column_name[ i ] .

加入线程

最后一个潜在问题。 join 语句实际上并不等待您创建的线程。它只是等待 6000 毫秒。如果由于某种原因任何线程花费的时间超过该时间,您在尝试检索线程结果时将会收到错误。要实际等待创建的线程,您必须使用 thread action="join" name=(list of thread names) {} 。我将把它作为练习留给读者(:

说实话,还有其他事情可以清理和/或改进,但希望这个冗长的漫无目的的线程解释了为什么首先会发生错误以及如何在将来使用线程时避免它们

关于coldfusion - Lucee/Adobe ColdFusion - 从线程设置/获取信息{},我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69827003/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com