在PowerShell中实施类似fork的进程克隆语义-无需大量重构

时间:2018-10-25 19:21:43

标签: powershell refactoring fork

出于下面说明的原因,我想在PowerShell脚本中仿真fork()语义(使用完整环境进行进程克隆,包括已加载的模块,函数和当前变量)。

我调查了

由于我的代码最初是如何构造和增长的,因此所有人都需要进行不同程度的重构-我目前还不确定重构的价值,但是冒险尝试可能是最好的方法。

Invoke-Parallel -ImportFunctions -ImportModules -ImportVariables看起来将是最接近我想要或想要的东西,但是......

我很高兴听到使用过这些基于RunSpace的各种替代方法的人的信息,以确保我走在正确的轨道上,并最有效地集中精力。

背景故事

我编写了一个相当复杂的PowerShell脚本,其中包含用于在断开连接的网络域/段之间移动文件的支持模块。最初是基于轮询的(睡眠一会儿,轮询源服务器中的文件,将它们移到目标文件夹,然后再进入睡眠状态),并且运行良好...

...直到我们遇到大文件被截断的问题:据我所知,Windows文件系统语义缺乏以编程方式验证文件已完成写入的100%可靠方式(锁是可选的,并非所有程序都锁定,LastWriteTime不会在写入文件时更新,Length会立即设置为最终长度,并且在写入过程中不会更新等)。如果您知道如何解决此问题,那么在PowerShell中 100%可靠可能也有帮助...!

由于它是如何开始的,将如何使用的,因此我的服务器实际上是一个整体的单线程控制线程编写的-这并不完全正确,但是足够接近,可以使您了解我在哪里我在。

然后,我转到一个简单的网络调用模型:用户准备要移动的文件,将它们放在源文件夹中,然后调用UDP客户端,该客户端向我的PowerShell进程发送一条简短的“进行此传输”消息,该消息是在几个网络接口上监听。

listenreadFromTheNetwork代码添加到现有的单线程控制过程中非常容易,我们已经摆脱了所有错误。它很健壮并且可以正常工作,所以我不愿进行重构,但是,这里有一个缺陷:它基本上只能处于以下三种状态之一:

  1. 等待请求
  2. 确认请求或返回已完成请求的确认,或
  3. 执行请求(将文件从A移到B,这可能需要很长时间)。

这意味着,如果在处理第一个请求时到达第二个请求,则最终将处理该请求,但无法确认-为了向用户提供反馈,我在调用客户端中设置了五秒钟的超时:如果没有响应在5内,假设服务忙碌或关闭,请检查它,或者稍后再试。

我想通过让进程启动一个单独的子任务来移动文件来为用户改善这一点,但是...

...操作的移动部分涉及很多状态(导入的功能和模块,网络凭据,网络位置,精细控制详细信息(是否执行完整性检查,是否过滤文件以及如何执行,等等。))。我发现似乎唯一接近的实用工具是Invoke-Parallel-这是我与社区联系的地方,以获取有关该实用工具和其他实用工具,恐怖故事等的经验。

很多年前,我在UNIX下编写了许多服务器,在Linux下编写了一些服务器:由于fork(),这很容易,{{1}}允许父服务器处理所有设置,代码导入,配置验证和监听/接受操作,然后创建一个可以使用从父级继承的现有状态独立执行所需操作的子级。 (当然,这不是完美的,我不得不担心重影过程和其他事情,但是主线(即父级)的寿命要比正在运行的子代长得多,并且如果死亡,则存在严重的错误情况,即需要人工干预。)

所以。假设我必须进行重构,那么您可以从哪种可用的替代方案中找到哪种最有效的方法,将大量进程状态从一个Windows进程转换为另一个Windows进程,从而最大程度地减少重构操作?

非常感谢。

0 个答案:

没有答案