我正在编写一个当前在 2.2.22 上运行的 Apache 模块。该模块运行以新编程语言编写的脚本,并且为了优化,它缓存解析结果以供后续使用。
由于在修改文件时应删除缓存的解析,因此我存储修改时间并在每次运行时对照文件系统进行检查。
这是一些带有调试消息的代码:
if (file->is_modified (mtime)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"P* removing cached file");
files.erase(it);
}
Run Code Online (Sandbox Code Playgroud)
我在测试这个(获取页面,修改文件,再次获取)时发现,这个块永远不会到达。该文件在更改后再次解析,但不是因为此检查。在我看来,Apache 本身正在检查修改时间并释放模块中的所有内存。
解析后的文件在未修改时可以正确重用。
这是 Apache 服务器的预期行为吗,如果是,这叫什么,它在哪里记录?
检查缓存程序的函数的完整代码
shared_ptr<pstar_file> pstar_pool::get_file_handle (
request_rec *r,
wpl_io &io,
const char *filename,
int mtime
)
{
pstar_map_t::iterator it;
apr_proc_mutex_lock (mutex);
// Check if a cached program exists
it = files.find(filename);
if (it != files.end()) {
if (it->second->is_modified (mtime)) {
files.erase(it);
}
else {
apr_proc_mutex_unlock (mutex);
return it->second;
}
}
apr_proc_mutex_unlock (mutex);
shared_ptr<pstar_file> file_ptr(new pstar_file(io, filename, mtime));
apr_proc_mutex_lock (mutex);
files.insert(std::pair<string,shared_ptr<pstar_file>>(filename, file_ptr));
apr_proc_mutex_unlock (mutex);
return file_ptr;
}
Run Code Online (Sandbox Code Playgroud)
Github 上整个模块的完整代码(多个文件):https : //github.com/atlesn/P-star/blob/master/src/apache2/pstar_pool.cpp
这里缺少相当多的上下文。不过,我认为答案可能很简单。
在实例化工作进程时加载模块。当一个模块被加载时,通常,它会被复制到内存中的过程映像中,磁盘上的更改不会影响它。这是否相关取决于您在自定义模块中执行的操作。
当然,当模块访问的文件被使用和更改时,apache 不会表现出奇怪或未定义的行为。如果您的模块打开一个文件,稍后对该文件进行修改以执行您所说的操作会很奇怪,尽管我觉得可能有一个不清楚的原因。
还要检查底层文件系统是否以您期望的方式实际存储和更新 mtime。并非总是如此。您的 mtime 检查(您未包括在内)也可能是错误的。
由于您说文件正在以某种未知方式重新加载,因此很可能正在为每个请求实例化一个新的工作进程,或者每次尝试都会获得不同的工作进程。
考虑在您的 mtime 检查中调试打印,以帮助隔离这一点。
归档时间: |
|
查看次数: |
150 次 |
最近记录: |