2013-08-01 2 views
2

우리는 Continuous Integration (CI) 서버 (CruiseControl.NET)에 단계를 통합하기 위해 노력하고 있습니다. 빌드 프로세스에서 생성 된 디버그 기호 *.pdb을 Microsoft Symbol Server에 등록하려고합니다. Microsoft에서 구현 한 기호 서버는 Visual Studio에서 C++/C# 실행 파일에 대한 디버그 기호 인 *.pdb을 찾는 데 사용하는 디렉터리 구조입니다. Microsoft는 한 디렉터리에서 디버그 기호를 사용하고 중앙 기호 저장소 디렉토리를 적절하게 채우는 명령 symstore을 제공합니다.Powershell 또는 BATCH를 통해 symstore를 직렬화

문제가있는 경우 symstore은 동시에 실행하는 것이 안전하지 않다고 명시되어 있습니다.

BATCH 또는 Powershell 스크립트를 통해 symstore 명령을 동시에 실행할 수 없도록 시도 할 수있는 방법이나 전략은 무엇입니까?

우리는 접근 방식에 유연하지만 Windows 플랫폼에서 실행되기 때문에 BATCH 및 Powershell이 ​​선호되는 솔루션입니다.

명확한 설명 : 공통의 네트워크 드라이브에 기호를 저장합니다 두 개의 서로 다른 CI 서버에서 실행 가능한 할 필요가 symstore 우리의 사용 사례에 대해서는

.

자료 :

symstore :: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681417(v=vs.85).aspx

+2

다른 컴퓨터에서 동일한 컴퓨터에서'symstore'를 실행해야합니까? 또는 다른 컴퓨터에서'symstore'를 실행하여 중앙 컴퓨터에 심볼 저장소를 관리해야합니까? –

+0

TFS 및 해당 빌드 프로세스 템플릿을 사용하여 심볼 저장소에 대한 액세스를 동기화 할 수 있습니다. 자세한 내용은 "SharedResourceScope 활동"을 참조하십시오. http://blogs.msdn.com/b/adamroot/archive/2009/06/17/source-server-and-symbol-server-features-in-team-foundation-server- 2010-beta-1.aspx –

답변

4

잠긴 파일을 간단한 세마포어로 사용하여 이벤트를 직렬화 할 수 있습니다. 배치 파일의 stdout을 파일로 재지 정하면 해당 파일에 독점 쓰기 잠금이 설정됩니다. 다른 프로세스가 쓰기 액세스를 위해 동일한 파일을 열 수 없습니다. 프로세스가 끝나면 프로세스가 완료 될 때 잠금이 자동으로 해제됩니다 (종료, CTRL-C, 예외 오류 등)

배치 파일은 9를 잠금 파일로 리디렉션하려고 시도 할 수 있으며 실패하면 성공할 때까지 되돌아 간다. symstore 명령은 잠금이 작동하는 동안에 만 실행됩니다. 비표준 파일 핸들 (stream?)은 잠금이 stdin, stdout 또는 stderr 처리를 방해하지 않도록 사용됩니다.

따라서 symstore를 직접 호출하지 않아도됩니다. 대신 배치 스크립트를 통해 항상 호출합니다. 다음 (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 대기열이 없다는 것입니다. 여러 개의 중복 요청이 수신되면 다음 단계로 넘어갈 무작위 추첨이됩니다. 그러나 프로세스가 직렬화됩니다.

편집 :
편집하기 전에 산산이 비트의 원본 답변을 읽었습니다. 그는 원격 컴퓨터에서 파일 잠금이 안정적인지 여부를 묻습니다. 몇 가지 빠른 Google 검색을했는데 UNC 경로에서 파일을 잠그는 데 문제가있는 것으로 보입니다. 문제가 발생하면 UNC 경로를 통해 직접 매핑 된 드라이브 문자 대신 파일로 리디렉션하는 것이 좋습니다. 이것은 모든 이론입니다. 나는 테스트를하지 않았습니다. 이 솔루션을 사용하기 전에 적절한 테스트를 수행하십시오. PUSHD는 사용 가능한 드라이브 문자를 몰라도 드라이브 문자를 UNC 경로에 임시로 할당하는 편리한 방법입니다. POPD는 드라이브 지정을 해제합니다.

+0

이것은 정확히 내가 기대했던 패러다임이었다 ... 상호 배타성을 제공하는 배치/powershell 래퍼. 일부 VM에 대한 사전 테스트가 잘됩니다. 나는 더 많은 테스트를하고 나서 받아 들일 것입니다! –

+0

@EricWebb - 내 대답을 편집하십시오. UNC 경로를 통한 잠금에 문제가있을 수 있습니다. – dbenham

+0

UNC 나 네트워크 드라이브가 어떤 경로인지는 중요하지 않습니다. 네트워크 파일 시스템과 관련이 있습니다. Windows는 네트워크 연결을 통해 파일에 액세스 할 때 파일 잠금을 보장 할 수 없습니다. –

-1

동시 실행을 방지하기 위해 세마포어로 공유 디렉토리에있는 파일을 사용합니다.

: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 

배치가 실패 할 수있는 모든 이상한 방법과 모든 불쾌한 경주 조건을 디버깅 할 준비를하십시오.

+1

이것은 나에게 경쟁 조건처럼 보입니다. sem.txt의 존재를 확인하고 생성 (잠금)하기 위해서는이 메소드가 작동하기 위해 원자 적이어야한다. 그렇지 않으면'sem.txt'를 생성하는 것이 이미 존재한다면 실패한다. –

+0

예, 나는이 세부 구현을 OP 또는 두 번째 질문에 맡겼습니다. –

+1

그 세부 사항은 진술 된 질문의 근본입니다! 즉, 크로스 컴퓨터 동시성에 관한 요점은 좋은 것입니다. –

0

네트워크 드라이브에 대한 액세스를 잠 그려면 두 가지 CI 서비스가 모두 통신하는 타사가 필요합니다. 그러면이 타사에서 네트워크 드라이브에 대한 액세스를 처리합니다. 이 세 번째 파티가 될 수 :

  • MSMQ에게
  • 데이터베이스 테이블에
  • symstore를 실행하고 CCNet이 기호 서버에 symstore
  • CCNet을 트리거 할 얘기를 구축 기호 서버에
  • WCF 서비스 원격 트리거 할 수있는 프로젝트/작업과
  • 당신의 CI 서버에서 원격 트리거 할 수있는 기호 서버에 예약 된 작업
+1

두 프로세스가 다른 호스트에서 실행되는 경우 문제가 해결되지 않습니다. –

+0

@PA 원래의 질문은 기계 간 요구 사항에 대해서는 언급하지 않았습니다. –

+0

당신이 맞다. 그렇지 않다. 나는 이전의 비슷한 시나리오에서 추측하고 있었다. (나는 당신의 대답을 downvote하지 않았다.) –

관련 문제