protected void doRun() throws Exception { SyncWatchEvent lastSyncWatchEvent = SyncWatchEventService.getLastSyncWatchEvent(_syncAccountId); if (lastSyncWatchEvent == null) { return; } long delta = System.currentTimeMillis() - lastSyncWatchEvent.getTimestamp(); if (delta <= 500) { SyncEngineUtil.fireSyncEngineStateChanged( _syncAccountId, SyncEngineUtil.SYNC_ENGINE_STATE_PROCESSING); return; } if (_logger.isTraceEnabled()) { _logger.trace("Processing Sync watch events"); } _pendingTypePKSyncFileIds.clear(); List<SyncWatchEvent> syncWatchEvents = null; if (OSDetector.isApple()) { syncWatchEvents = SyncWatchEventService.findBySyncAccountId(_syncAccountId); } else { syncWatchEvents = SyncWatchEventService.findBySyncAccountId(_syncAccountId, "eventType", true); } for (SyncWatchEvent syncWatchEvent : syncWatchEvents) { processSyncWatchEvent(syncWatchEvent); } for (Map.Entry<String, List<SyncWatchEvent>> entry : _dependentSyncWatchEventsMaps.entrySet()) { SyncFile syncFile = SyncFileService.fetchSyncFile(entry.getKey()); if ((syncFile != null) && (syncFile.getTypePK() > 0)) { for (SyncWatchEvent syncWatchEvent : entry.getValue()) { processSyncWatchEvent(syncWatchEvent); } } } SyncEngineUtil.fireSyncEngineStateChanged( _syncAccountId, SyncEngineUtil.SYNC_ENGINE_STATE_PROCESSED); _processedSyncWatchEventIds.clear(); }
protected synchronized void processSyncWatchEvent(SyncWatchEvent syncWatchEvent) throws Exception { SyncAccount syncAccount = SyncAccountService.fetchSyncAccount(_syncAccountId); if (syncAccount.getState() != SyncAccount.STATE_CONNECTED) { return; } if (_processedSyncWatchEventIds.contains(syncWatchEvent.getSyncWatchEventId())) { SyncWatchEventService.deleteSyncWatchEvent(syncWatchEvent.getSyncWatchEventId()); return; } String eventType = syncWatchEvent.getEventType(); if (eventType.equals(SyncWatchEvent.EVENT_TYPE_RENAME_FROM)) { eventType = SyncWatchEvent.EVENT_TYPE_DELETE; syncWatchEvent.setEventType(eventType); SyncWatchEventService.update(syncWatchEvent); } if (_logger.isDebugEnabled()) { _logger.debug("Processing Sync watch event {}", syncWatchEvent.toString()); } String fileType = syncWatchEvent.getFileType(); if (eventType.equals(SyncWatchEvent.EVENT_TYPE_CREATE)) { if (fileType.equals(SyncFile.TYPE_FILE)) { SyncWatchEvent duplicateSyncWatchEvent = null; if (OSDetector.isApple()) { duplicateSyncWatchEvent = SyncWatchEventService.fetchDuplicateSyncWatchEvent(syncWatchEvent); } if (duplicateSyncWatchEvent != null) { if (_logger.isDebugEnabled()) { _logger.debug("Skipping outdated Sync watch event"); } } else { addFile(syncWatchEvent); } } else { addFolder(syncWatchEvent); } } else if (eventType.equals(SyncWatchEvent.EVENT_TYPE_DELETE)) { deleteFile(syncWatchEvent); } else if (eventType.equals(SyncWatchEvent.EVENT_TYPE_MODIFY)) { SyncWatchEvent duplicateSyncWatchEvent = SyncWatchEventService.fetchDuplicateSyncWatchEvent(syncWatchEvent); if (duplicateSyncWatchEvent != null) { if (_logger.isDebugEnabled()) { _logger.debug("Skipping outdated Sync watch event"); } } else { modifyFile(syncWatchEvent); } } else if (eventType.equals(SyncWatchEvent.EVENT_TYPE_MOVE)) { moveFile(syncWatchEvent); } else if (eventType.equals(SyncWatchEvent.EVENT_TYPE_RENAME)) { renameFile(syncWatchEvent); } syncAccount = SyncAccountService.fetchSyncAccount(_syncAccountId); if (syncAccount.getState() == SyncAccount.STATE_CONNECTED) { SyncWatchEventService.deleteSyncWatchEvent(syncWatchEvent.getSyncWatchEventId()); } }
protected void sendFile( final ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest, SyncFile syncFile) throws Exception { Path path = Paths.get(syncFile.getFilePathName()); if (Files.notExists(path)) { _syncTrafficShapingHandler.decrementConnectionsCount(); if (_logger.isTraceEnabled()) { Channel channel = channelHandlerContext.channel(); _logger.trace("Client {}: file not found {}", channel.remoteAddress(), path); } _sendError(channelHandlerContext, NOT_FOUND); return; } if (_logger.isDebugEnabled()) { Channel channel = channelHandlerContext.channel(); _logger.debug("Client {}: sending file {}", channel.remoteAddress(), path); } long modifiedTime = syncFile.getModifiedTime(); long previousModifiedTime = syncFile.getPreviousModifiedTime(); if (OSDetector.isApple()) { modifiedTime = modifiedTime / 1000 * 1000; previousModifiedTime = previousModifiedTime / 1000 * 1000; } FileTime currentFileTime = Files.getLastModifiedTime(path, LinkOption.NOFOLLOW_LINKS); long currentTime = currentFileTime.toMillis(); if ((currentTime != modifiedTime) && (currentTime != previousModifiedTime)) { _syncTrafficShapingHandler.decrementConnectionsCount(); Channel channel = channelHandlerContext.channel(); _logger.error( "Client {}: file modified {}, currentTime {}, modifiedTime " + "{}, previousModifiedTime {}", channel.remoteAddress(), path, currentTime, modifiedTime, previousModifiedTime); _sendError(channelHandlerContext, NOT_FOUND); return; } HttpResponse httpResponse = new DefaultHttpResponse(HTTP_1_1, OK); long size = Files.size(path); HttpUtil.setContentLength(httpResponse, size); HttpHeaders httpHeaders = httpResponse.headers(); MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap(); httpHeaders.set( HttpHeaderNames.CONTENT_TYPE, mimetypesFileTypeMap.getContentType(syncFile.getName())); if (HttpUtil.isKeepAlive(fullHttpRequest)) { httpHeaders.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); } channelHandlerContext.write(httpResponse); SyncChunkedFile syncChunkedFile = new SyncChunkedFile(path, size, 4 * 1024 * 1024, currentTime); ChannelFuture channelFuture = channelHandlerContext.writeAndFlush( new HttpChunkedInput(syncChunkedFile), channelHandlerContext.newProgressivePromise()); channelFuture.addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture channelFuture) throws Exception { _syncTrafficShapingHandler.decrementConnectionsCount(); if (channelFuture.isSuccess()) { return; } Throwable exception = channelFuture.cause(); Channel channel = channelHandlerContext.channel(); _logger.error( "Client {}: {}", channel.remoteAddress(), exception.getMessage(), exception); channelHandlerContext.close(); } }); if (!HttpUtil.isKeepAlive(fullHttpRequest)) { channelFuture.addListener(ChannelFutureListener.CLOSE); } }