-
Bug
-
Resolution: Unresolved
-
Minor
-
Jenkins Version : 2.121.1
p4plugin Version : 1.8.10/Mac_OS_X
Operating System (Master): Mac OS X / 10.12.6
JRE (master) : Oracle 1.8.0_1.6.1
Operating System (Slave) : Mac OS X / 10.12.6
JRE (slave) : Oracle 1.8.0_1.6.1
Running Jenkins via the War / .jenkins setup on our Master, run via terminal.
Installed via web download.
Slave nodes are being launched via SSH
Web browser : Safari / Chrome (Version 69.0.3497.100 (Official Build) (64-bit)
)
Jenkins Version : 2.121.1 p4plugin Version : 1.8.10/Mac_OS_X Operating System (Master): Mac OS X / 10.12.6 JRE (master) : Oracle 1.8.0_1.6.1 Operating System (Slave) : Mac OS X / 10.12.6 JRE (slave) : Oracle 1.8.0_1.6.1 Running Jenkins via the War / .jenkins setup on our Master, run via terminal. Installed via web download. Slave nodes are being launched via SSH Web browser : Safari / Chrome (Version 69.0.3497.100 (Official Build) (64-bit) )
We have a build system set up, where the master hands out jobs to the slaves. The slave will p4sync a version information text file to determine which application file that it needs to download via another p4sync call to start its build process.
In some cases the p4 sync call completes, (we have verbose on), and let's us know which version of the file it was able to find, with revision information. We immediately call readFile, and a NoSuchFileException is thrown. (or the file is empty)
*09:08:31* java.nio.file.NoSuchFileException: /Users/current_user/.jenkins-LightWeight/workspace/job_name-617/ProjectVersion.txt *09:08:31* at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86) *09:08:31* at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102) *09:08:31* at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107) *09:08:31* at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214) *09:08:31* at java.nio.file.Files.newByteChannel(Files.java:361) *09:08:31* at java.nio.file.Files.newByteChannel(Files.java:407) *09:08:31* at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384) *09:08:31* at java.nio.file.Files.newInputStream(Files.java:152) *09:08:31* at hudson.FilePath$Read.invoke(FilePath.java:1906) *09:08:31* at hudson.FilePath$Read.invoke(FilePath.java:1898) *09:08:31* at hudson.FilePath$FileCallableWrapper.call(FilePath.java:2918) *09:08:31* at hudson.remoting.UserRequest.perform(UserRequest.java:210) *09:08:31* at hudson.remoting.UserRequest.perform(UserRequest.java:53) *09:08:31* at hudson.remoting.Request$2.run(Request.java:364) *09:08:31* at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72) *09:08:31* Caused: java.io.IOException *09:08:31* at hudson.remoting.FastPipedInputStream.read(FastPipedInputStream.java:169) *09:08:31* at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) *09:08:31* at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) *09:08:31* at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) *09:08:31* at java.io.InputStreamReader.read(InputStreamReader.java:184) *09:08:31* at java.io.Reader.read(Reader.java:140) *09:08:31* at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2001) *09:08:31* at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1980) *09:08:31* at org.apache.commons.io.IOUtils.copy(IOUtils.java:1957) *09:08:31* at org.apache.commons.io.IOUtils.copy(IOUtils.java:1907) *09:08:31* at org.apache.commons.io.IOUtils.toString(IOUtils.java:778) *09:08:31* at org.apache.commons.io.IOUtils.toString(IOUtils.java:803) *09:08:31* at org.jenkinsci.plugins.workflow.steps.ReadFileStep$Execution.run(ReadFileStep.java:97) *09:08:31* at org.jenkinsci.plugins.workflow.steps.ReadFileStep$Execution.run(ReadFileStep.java:86) *09:08:31* at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution$1$1.call(SynchronousNonBlockingStepExecution.java:49) *09:08:31* at hudson.security.ACL.impersonate(ACL.java:290) *09:08:31* at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution$1.run(SynchronousNonBlockingStepExecution.java:46) *09:08:31* at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) *09:08:31* at java.util.concurrent.FutureTask.run(FutureTask.java:266) *09:08:31* at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) *09:08:31* at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) *09:08:31* at java.lang.Thread.run(Thread.java:748)
To work around this, I threw in some retries and sleeps. The idea being that it will attempt repeatedly to readFile until the file is there (120 tries, 1 second apart), and if that fails , it will attempt the p4 sync again. Usually this will work on the second try, if not the retry logic takes over again. In some rarer cases, the file will be empty, so we throw and error and it starts over.
Is there any reason that the file system would have some long delay between p4 sync completely and the file being available? We don't have the parallel functionality on for p4. We have no other threads on any of the machines interacting with the workspaces. This work around works for now, but we have no idea why the file would not be there, or not have contents. About 1/50 - 1/100 of our jobs run into this issue, it seems random.
Is there a better way to readFile after a p4Sync to guarantee that the file is in fact there, and has contents?
Example code:
stage('Example Stage') { steps { script { // Local path to our project version def projectVersionFilePath = "//${PathToTrunk}/ProjectSettings/ProjectVersion.txt " echo 'projectVersionView - ' + projectVersionView def projectVersionFileContent = null; def MAX_PROJECT_VERSION_SYNC_ATTEMPTS = 5; def PROJECT_VERSION_SYNC_SLEEP_TIME = 5; int numSyncAttempts = 0; try { // We have this retry, because in some cases // even after 120 retries (about 120 seconds) // it still can't open the file retry(MAX_PROJECT_VERSION_SYNC_ATTEMPTS) { if (numSyncAttempts > 0) { sleep PROJECT_VERSION_SYNC_SLEEP_TIME } numSyncAttempts++; // In all cases this will tell us the file and revision number that we want p4sync charset: 'none', credential: 'VALID_CREDENTIAL', format: 'Jenkins-${NODE_NAME}-${JOB_NAME}-${EXECUTOR_NUMBER}', populate: forceClean(have: false, parallel: [enable: false, minbytes: '1024', minfiles: '1', threads: '4'], pin: '', quiet: false), source: depotSource(projectVersionFilePath) int numReadAttempts = 0; def MAX_PROJECT_VERSION_READ_ATTEMPTS = 120; def PROJECT_VERSION_READ_SLEEP_TIME = 1; // We have this retry because sometimes // the file isn't available to be read even if the p4 sync has completed "correctly" retry(MAX_PROJECT_VERSION_READ_ATTEMPTS) { if (numReadAttempts > 0) { sleep projectVersionReadSleepTimeSeconds; } numReadAttempts++; // this will in some cases fail, for reasons unknown to me projectVersionFileContent = readFile 'ProjectVersion.txt'; // in stranger situations the file will read, // but will be empty if (0 == fileContent.length()) { error '0 == fileContent.length' } } } } catch (e) { echo 'failed getting ProjectVersion.txt' throw e; } echo 'PROJECT VERSION : ' + projectVersionFileContent; } } }