我在build.gradle文件中使用P4Java库来同步驻留在远程Perforce存储库中的大型zip文件(> 200MB),但是在同步过程或以下过程中遇到“java.net.SocketTimeoutException:读取超时”错误(主要是)在删除为同步操作创建的临时客户端的过程中。我指的是http://razgulyaev.blogspot.in/2011/08/p4-java-api-how-to-work-with-temporary.html用于使用P4Java API的临时客户端。
我尝试按照http://answers.perforce.com/articles/KB/8044的建议将套接字读取超时从默认的30秒增加到默认值,并且还尝试引入睡眠,但是两种方法都无法解决问题。在执行同步或删除操作之前,先使用getServerInfo()对服务器进行探查以确保成功进行连接检查。有人可以指出我应该在哪里寻找答案吗?
谢谢。
提供代码段:
void perforceSync(String srcPath, String destPath, String server) {
// Generating the file(s) to sync-up
String[] pathUnderDepot = [
srcPath + "*"
]
// Increasing timeout from default 30 sec to 60 sec
Properties defaultProps = new Properties()
defaultProps.put(PropertyDefs.PROG_NAME_KEY, "CustomBuildApp")
defaultProps.put(PropertyDefs.PROG_VERSION_KEY, "tv_1.0")
defaultProps.put(RpcPropertyDefs.RPC_SOCKET_SO_TIMEOUT_NICK, "60000")
// Instantiating the server
IOptionsServer p4Server = ServerFactory.getOptionsServer("p4java://" + server, defaultProps)
p4Server.connect()
// Authorizing
p4Server.setUserName("perforceUserName")
p4Server.login("perforcePassword")
// Just check if connected successfully
IServerInfo serverInfo = p4Server.getServerInfo()
println 'Server info: ' + serverInfo.getServerLicense()
// Creating new client
IClient tempClient = new Client()
// Setting up the name and the root folder
tempClient.setName("tempClient" + UUID.randomUUID().toString().replace("-", ""))
tempClient.setRoot(destPath)
tempClient.setServer(p4Server)
// Setting the client as the current one for the server
p4Server.setCurrentClient(tempClient)
// Creating Client View entry
ClientViewMapping tempMappingEntry = new ClientViewMapping()
// Setting up the mapping properties
tempMappingEntry.setLeft(srcPath + "...")
tempMappingEntry.setRight("//" + tempClient.getName() + "/...")
tempMappingEntry.setType(EntryType.INCLUDE)
// Creating Client view
ClientView tempClientView = new ClientView()
// Attaching client view entry to client view
tempClientView.addEntry(tempMappingEntry)
tempClient.setClientView(tempClientView)
// Registering the new client on the server
println p4Server.createClient(tempClient)
// Surrounding the underlying block with try as we want some action
// (namely client removing) to be performed in any way
try {
// Forming the FileSpec collection to be synced-up
List<IFileSpec> fileSpecsSet = FileSpecBuilder.makeFileSpecList(pathUnderDepot)
// Syncing up the client
println "Syncing..."
tempClient.sync(FileSpecBuilder.getValidFileSpecs(fileSpecsSet), true, false, false, false)
}
catch (Exception e) {
println "Sync failed. Trying again..."
sleep(60 * 1000)
tempClient.sync(FileSpecBuilder.getValidFileSpecs(fileSpecsSet), true, false, false, false)
}
finally {
println "Done syncing."
try {
p4Server.connect()
IServerInfo serverInfo2 = p4Server.getServerInfo()
println '\nServer info: ' + serverInfo2.getServerLicense()
// Removing the temporary client from the server
println p4Server.deleteClient(tempClient.getName(), false)
}
catch(Exception e) {
println 'Ignoring exception caught while deleting tempClient!'
/*sleep(60 * 1000)
p4Server.connect()
IServerInfo serverInfo3 = p4Server.getServerInfo()
println '\nServer info: ' + serverInfo3.getServerLicense()
sleep(60 * 1000)
println p4Server.deleteClient(tempClient.getName(), false)*/
}
}
}
我在删除tempClient时观察到的一件不寻常的事情是,它实际上是在删除客户端,但仍然抛出“java.net.SocketTimeoutException:读取超时”,这就是为什么我最终在第二个catch块中评论第二次删除尝试的原因。
最佳答案
您正在使用哪个版本的P4Java?您是否使用最新的P4Java进行了尝试?自2013.2版本向前以来,有一些针对RPC套接字的重要修复程序,如发行说明所示:
http://www.perforce.com/perforce/doc.current/user/p4javanotes.txt
以下是一些变体,您可以尝试在其中放置代码的地方增加超时并实例化服务器:
a]您是否尝试过按照自己的观点传递 Prop ?例如:
Properties prop = new Properties();
prop.setProperty(RpcPropertyDefs.RPC_SOCKET_SO_TIMEOUT_NICK, "300000");
UsageOptions uop = new UsageOptions(prop);
server = ServerFactory.getOptionsServer(ServerFactory.DEFAULT_PROTOCOL_NAME + "://" + serverPort, prop, uop);
或类似以下内容:
IOptionsServer p4Server = ServerFactory.getOptionsServer("p4java://" + server, defaultProps)
您也可以将超时设置为“0”,使其不超时。
b]
props.put(RpcPropertyDefs.RPC_SOCKET_SO_TIMEOUT_NICK, "60000");
props.put(RpcPropertyDefs.RPC_SOCKET_POOL_SIZE_NICK, "5");
C]
Properties props = System.getProperties();
props.put(RpcPropertyDefs.RPC_SOCKET_SO_TIMEOUT_NICK, "60000");
IOptionsServer server =
ServerFactory.getOptionsServer("p4java://perforce:1666", props, null);
d]如果您有使用我们的P4Eclipse插件的Eclipse用户,则可以在“定制P4Java属性”下的插件首选项(“团队”->“Perforce”->“高级”)中设置该属性。
“sockSoTimeout”:“3000000”
引用资料
http://perforce.com/perforce/doc.current/manuals/p4java-javadoc/com/perforce/p4java/impl/mapbased/rpc/RpcPropertyDefs.html
http://answers.perforce.com/articles/KB/8044