! ========================================================================
! Copyright (C) VMware, Inc. 1991-2011.  All Rights Reserved
!
! $Id: GsParallelAudit.gs,v 1.4 2008-01-09 22:50:07 stever Exp $
!
! ========================================================================
!
doit
Object subclass: 'GsParallelAudit'
  instVarNames: #()
  classVars: #()
  classInstVars: #()
  poolDictionaries: #[]
  inDictionary: Globals
  constraints: #[  ]
  instancesInvariant: false
  isModifiable: false

%
! Remove existing behavior from GsParallelAudit
doit
GsParallelAudit removeAllMethods.
GsParallelAudit class removeAllMethods.
%
! ------------------- Class methods for GsParallelAudit
category: 'Services'
classmethod: GsParallelAudit
audit: anNsc using: remoteGemCount

  | netldiName |
  netldiName := (System performOnServer: 'echo $gs64ldi') trimWhiteSpace.
  netldiName isEmpty
   ifTrue: [ self error: '$gs64ldi not set'].
  ^self audit: anNsc using: remoteGemCount netldiName: netldiName
%
category: 'Services'
classmethod: GsParallelAudit
audit: anNsc using: remoteGemCount netldiName: netldiName

  | queueName master server responseArray unit  resultString noIndex indexOk auditError res  gciInterfaces stdout |
queueName := #MasterQ_Audit.
stdout := GsFile stdoutServer.
stdout log: 'Starting parallel audit: ', self asOop printString.
master := GsWorkMaster attach: queueName.
gciInterfaces := self createRemoteSessions: remoteGemCount queueName: queueName netldiName: netldiName.
"only need 2 gems to do the work"
unit := GsWorkUnit execute: [:nsc |
  nsc _fastAuditEqualityIndexes.
] with: args.
master schedule: unit.
unit := GsWorkUnit execute: [:nsc |
  nsc _fastAuditIdentityIndexes.
] with: args.
master schedule: unit.
stdout log: 'Scheduling complete'.

server := GsWorkServer attach: queueName.
stdout log: 'My service loop: ', server asOop printString.
server serviceLoop: [ server queue isWorkQEmpty not ].
resultString := String new.
auditError := noIndex := indexOk := false.
stdout log: 'Reap results'.
[ master isEmpty ] whileFalse: [
  responseArray := master getAllResponses: 500.
  [ responseArray isEmpty ] whileTrue: [
    System sleep: 1.
    responseArray := master getAllResponses: 500.
  ].
  responseArray do: [:response |
    response error 
      ifTrue: [
        resultString := resultString, response stackReport.
        auditError := true.
     ].
    res := response result.
    (res = 'No indexes are present.')
      ifTrue: [ noIndex := true ]
      ifFalse: [
        (res = 'Indexes are OK')
          ifTrue: [ indexOk := true ]
          ifFalse: [ 
            resultString := resultString, res.
            auditError := true.
         ].
      ]
  ].
].
self shutdownRemoteSessions: gciInterfaces.
master teardown.
auditError ifTrue: [ ^resultString ].
indexOk ifTrue: [ ^'Indexes are OK' ].
noIndex ifTrue: [ ^'No indexes are present.' ].
^'Parallel audit error'
%
category: 'Private'
classmethod: GsParallelAudit
createRemoteSessions: remoteGemCount queueName: queueName netldiName: netldiName

  | ar gciInterface parameters netldiStr res |
ar := Array new.
1 to: remoteGemCount do: [:i |
  gciInterface := GciInterface new.
  parameters := GemStoneParameters new.
  parameters gemService: '!tcp#netldi:', netldiName, '#task!gemnetobject'.
  parameters gemStoneName: System stoneName.
  parameters username: System myUserProfile userId.
  parameters password: 'swordfish' copy.
  
  gciInterface nbLogin: parameters.
  [
      res := gciInterface nbEndBoolean.
      res == nil 
        ifTrue: [
          | descr ex |
          descr := gciInterface lastError.
          ex := Error new.
          ex gsNumber: descr number; gsArguments: descr message; yourself.
          ex signal. 
        ].
      res == 1.
    ] whileFalse: [
      System _sleepMs: 20.
  ].
  gciInterface nbRemoteExecute: '(GsWorkServer attach: ', queueName printString, ' ) serviceLoop'.
  ar add: gciInterface.
].
^ar
%
category: 'Private'
classmethod: GsParallelAudit
shutdownRemoteSessions: gciInterfaces

gciInterfaces do: [:gciInterface |
  gciInterface callInProgress ifTrue: [gciInterface hardBreak].
  gciInterface logout.
].
%
! ------------------- Instance methods for GsParallelAudit
