我们正在努力将一个步骤集成到我们的持续集成(CI)服务器(CruiseControl.NET)中。我们希望将构建过程中生成的调试符号*.pdb注册到Microsoft符号服务器中。正如微软实现的那样,符号服务器是Visual用来为C++/C#可执行文件查找*.pdb调试符号的目录结构。微软提供了一个命令symstore,它在一个目录中接受调试符号,并酌情填充中央符号存储目录。
问题是symstore显式地声明并发运行是不安全的。
我们可以尝试哪些方法或策略来禁止通过批处理或Powershell脚本并发执行symstore命令?
我们在方法上是灵活的,但是由于我们在Windows平台上运行,批处理和Powershell是首选的解决方案。
Clarification:
对于我们的用例,symstore需要在两个不同的CI服务器上运行,这将在一个普通的网络驱动器上保存符号。
资源:
符号商店::http://msdn.microsoft.com/en-us/library/windows/desktop/ms681417(v=vs.85).aspx
发布于 2013-08-01 22:14:11
您可以使用锁定的文件作为一个简单的信号量来序列化事件。当您将stdout重定向到批处理文件中的文件时,它将在该文件上建立独占写入锁。任何其他进程都不能打开相同的文件进行写访问。该锁将在进程结束时自动释放,无论它如何结束(清除退出、CTRL-C、异常失败等)。
批处理文件可以尝试将9重定向到锁文件,如果失败,则返回直到成功。符号存储命令只有在锁就位时才能运行。非标准文件句柄(流?)用于使锁不干扰stdin、stdout或stderr处理。
所以你只需要确保你永远不要直接打给符号商店。相反,您总是通过批处理脚本调用它。类似于以下内容(serializeSymstore.bat):
@echo off
setlocal
:loop
:: Save stderr definition and redirect stderr to nul
:: to hide possible redirection error when establishing lock.
8>&2 2>nul (
%= Attempt to establish the lock and restore stderr =%
9>"\\centralServer\somePath\symstore.lock" 2>&8 (
%= If got here then lock is established throughout all commands =%
%= in this set of parentheses. =%
%= Execute your command =%
symstore %*
%= Save the return code =%
call set "rtnCd=%%errorlevel%%"
%= The next command is a very fast way to clear the ERRORLEVEL. =%
%= We don't want symstore failure to trigger a loop. =%
(call )
)
) || (
%= If entered here then failed to establish lock. =%
%= Wait 1 second and then loop back to retry. =%
%= Replace with PING delay if TIMEOUT not universally available. =%
timeout 1 /nobreak >nul
goto loop
)
:: Exit with appropriate return code
exit /b %rtnCd%如果没有注释,它就会变成一小部分代码。
@echo off
setlocal
:loop
8>&2 2>nul (
9>"\\centralServer\somePath\symstore.lock" 2>&8 (
symstore %*
call set "rtnCd=%%errorlevel%%"
(call )
)
) || (
timeout 1 /nobreak >nul
goto loop
)
exit /b %rtnCd%我发现这个原始而简单的策略在许多项目中是非常有效的。我必须承认,我还没有在远程机器上测试锁和释放特性。但我认为只要所有的机器都是Windows,它就应该是可靠的。
我知道的唯一缺点是没有FIFO队列。如果接收到多个重叠请求,那么抽签的随机运气将决定下一步的进程。但是进程将被序列化。
编辑:
在编辑之前,我读过飞溅比特的原始答案。他质疑远程机器上的文件锁定是否可靠。我做了一些快速谷歌搜索,似乎确实存在一些问题,文件锁定在UNC路径。如果遇到问题,您可能会更幸运地重定向到映射驱动器号上的文件,而不是直接通过UNC路径。这都是理论-我没有做过测试。在承诺使用此解决方案之前,请确保进行充分的测试。请注意,PUSHD是一种方便的方法,可以暂时将驱动器字母分配到UNC路径,而不知道有哪些驱动器字母可用。POPD将解除驱动器分配的映射。
发布于 2013-08-01 19:11:48
为了锁定对网络驱动器的访问权限,您将需要一个与您的CI服务对话的第三方。然后这个第三方将处理对网络驱动器的访问。这一第三方可能是:
symstore的符号服务器上使用WCF服务,您的CCNet会与它建立对话以触发symstore。发布于 2013-08-01 19:05:56
使用共享目录中的文件作为信号量,以避免并发执行。
:checkfile
if exist %cidir%\sem.txt goto :wait10secs
echo gotit! >%cidir%\sem.txt
doit
del %cidir%\sem.txt
goto :eof
:wait10secs
ing 192.0.2.2 -n 1 -w 10000 > nul
goto :checkfile准备调试所有奇怪的方式,您的批处理可能失败和所有恶劣的赛车条件。
https://stackoverflow.com/questions/18002294
复制相似问题