feat: 实现员工同步任务的WebSocket支持及合同名称锁定功能
- 为EmployeesSyncTask添加WebSocket客户端和服务端支持,实现实时任务进度反馈 - 新增合同名称锁定功能,防止误修改重要合同名称 - 优化SmbFileService的连接异常处理,提高稳定性 - 重构ContractFilesRebuildTasker的任务执行逻辑,改进错误处理 - 更新tasker_mapper.json注册EmployeesSyncTask - 添加相关任务文档和验收报告 修复WebSocketClientSession的任务完成状态处理问题 改进UITools中任务执行的线程管理 优化DepartmentService的findByCode方法返回类型
This commit is contained in:
@@ -15,7 +15,6 @@ import com.hierynomus.smbj.SMBClient;
|
||||
import com.hierynomus.smbj.auth.AuthenticationContext;
|
||||
import com.hierynomus.smbj.common.SMBRuntimeException;
|
||||
import com.hierynomus.smbj.common.SmbPath;
|
||||
import com.hierynomus.smbj.event.SessionLoggedOff;
|
||||
import com.hierynomus.smbj.share.DiskShare;
|
||||
import com.hierynomus.smbj.share.File;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -25,6 +24,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.SocketException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@@ -271,6 +271,7 @@ public class SmbFileService implements DisposableBean {
|
||||
// 更新连接的最后使用时间
|
||||
connectionInfo.updateLastUsedTimestamp();
|
||||
log.debug("Reusing SMB connection for host: {}", hostname);
|
||||
|
||||
return connectionInfo;
|
||||
}
|
||||
log.debug("Closing invalid SMB connection for host: {}", hostname);
|
||||
@@ -289,7 +290,6 @@ public class SmbFileService implements DisposableBean {
|
||||
} finally {
|
||||
connectionPoolLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -305,6 +305,27 @@ public class SmbFileService implements DisposableBean {
|
||||
return getConnectionInfo(hostname).getConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断异常是否为连接相关异常
|
||||
*
|
||||
* @param e 异常
|
||||
* @return 如果是连接相关异常返回true,否则返回false
|
||||
*/
|
||||
private boolean isConnectionException(Exception e) {
|
||||
if (e instanceof SMBRuntimeException) {
|
||||
Throwable cause = e.getCause();
|
||||
while (cause != null) {
|
||||
if (cause instanceof TransportException || cause instanceof SocketException) {
|
||||
return true;
|
||||
}
|
||||
cause = cause.getCause();
|
||||
}
|
||||
} else if (e instanceof IOException) {
|
||||
return e instanceof SocketException || e.getMessage().contains("连接");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Session空闲超时时间:2分钟(比连接超时时间短)
|
||||
private static final long SESSION_IDLE_TIMEOUT_MS = 2 * 60 * 1000;
|
||||
|
||||
@@ -416,6 +437,15 @@ public class SmbFileService implements DisposableBean {
|
||||
log.debug("Created new SMB session for host: {}", hostname);
|
||||
} catch (SMBRuntimeException ex) {
|
||||
log.error("Failed to create SMB session for host: {}, maxTrys:{}", hostname, maxTrys, ex);
|
||||
// 检查是否是连接问题,如果是则从池中移除连接
|
||||
if (isConnectionException(ex)) {
|
||||
connectionPoolLock.lock();
|
||||
try {
|
||||
connectionPool.remove(hostname);
|
||||
} finally {
|
||||
connectionPoolLock.unlock();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
@@ -435,6 +465,10 @@ public class SmbFileService implements DisposableBean {
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
log.error("Failed to execute SMB operation for host: {}, maxTrys:{}", hostname, maxTrys, e);
|
||||
// 检查是否是连接问题,如果是则从池中移除连接
|
||||
if (isConnectionException(e)) {
|
||||
connectionPool.remove(hostname);
|
||||
}
|
||||
continue;
|
||||
} finally {
|
||||
|
||||
@@ -451,6 +485,11 @@ public class SmbFileService implements DisposableBean {
|
||||
log.debug("Removed disconnected SMB connection from pool for host: {}", hostname);
|
||||
}
|
||||
}
|
||||
// 如果是连接异常且还有重试次数,继续重试
|
||||
if (isConnectionException(e) && maxTrys > 0) {
|
||||
log.debug("Retrying SMB operation due to connection exception, remaining tries: {}", maxTrys);
|
||||
continue;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user