mirror of https://github.com/halo-dev/halo
				
				
				
			fix: handle plugin entry file loading when cache temp directory is cleared (#6238)
#### What type of PR is this? /kind bug /area plugin /milestone 2.17.x #### What this PR does / why we need it: 修复当插件入口文件的缓存目录被系统清理后会导致一直无法加载的问题 原问题复现步骤: 1. 登录后刷新页面,此时缓存目录被创建 2. 删除缓存目录后就会提示文件不存在然后导致插件入口文件一致无法加载直到重启 Halo #### Which issue(s) this PR fixes: Fixes #6226 #### Does this PR introduce a user-facing change? ```release-note 修复当插件入口文件的缓存目录被系统清理后会导致一直无法加载的问题 ```pull/6279/head v2.17.0-rc.1
							parent
							
								
									cc3564bf82
								
							
						
					
					
						commit
						b9c500dc8d
					
				| 
						 | 
				
			
			@ -549,15 +549,22 @@ public class PluginServiceImpl implements PluginService, InitializingBean, Dispo
 | 
			
		|||
                            // double check of the resource
 | 
			
		||||
                            .filter(res -> isResourceMatch(res, newFilename))
 | 
			
		||||
                            .switchIfEmpty(Mono.using(
 | 
			
		||||
                                    () -> tempDir.resolve(newFilename),
 | 
			
		||||
                                    () -> {
 | 
			
		||||
                                        if (!Files.exists(tempDir)) {
 | 
			
		||||
                                            Files.createDirectories(tempDir);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        return tempDir.resolve(newFilename);
 | 
			
		||||
                                    },
 | 
			
		||||
                                    path -> DataBufferUtils.write(content, path,
 | 
			
		||||
                                            CREATE, TRUNCATE_EXISTING)
 | 
			
		||||
                                        .then(Mono.<Resource>fromSupplier(
 | 
			
		||||
                                            () -> new FileSystemResource(path)
 | 
			
		||||
                                        )),
 | 
			
		||||
                                    path -> {
 | 
			
		||||
                                        // clean up old resource
 | 
			
		||||
                                        cleanUp(this.resource);
 | 
			
		||||
                                        if (shouldCleanUp(path)) {
 | 
			
		||||
                                            // clean up old resource
 | 
			
		||||
                                            cleanUp(this.resource);
 | 
			
		||||
                                        }
 | 
			
		||||
                                    })
 | 
			
		||||
                                .subscribeOn(scheduler)
 | 
			
		||||
                                .doOnNext(newResource -> this.resource = newResource)
 | 
			
		||||
| 
						 | 
				
			
			@ -579,6 +586,18 @@ public class PluginServiceImpl implements PluginService, InitializingBean, Dispo
 | 
			
		|||
                });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private boolean shouldCleanUp(Path newPath) {
 | 
			
		||||
            if (this.resource == null || !this.resource.exists()) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            try {
 | 
			
		||||
                var oldPath = this.resource.getFile().toPath();
 | 
			
		||||
                return !oldPath.equals(newPath);
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void cleanUp(Resource resource) {
 | 
			
		||||
            if (resource instanceof WritableResource wr
 | 
			
		||||
                && wr.isWritable()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
 | 
			
		|||
import org.pf4j.PluginDescriptor;
 | 
			
		||||
import org.pf4j.PluginWrapper;
 | 
			
		||||
import org.springframework.core.io.buffer.DataBuffer;
 | 
			
		||||
import org.springframework.util.FileSystemUtils;
 | 
			
		||||
import org.springframework.web.server.ServerWebInputException;
 | 
			
		||||
import reactor.core.publisher.Mono;
 | 
			
		||||
import reactor.test.StepVerifier;
 | 
			
		||||
| 
						 | 
				
			
			@ -391,6 +392,24 @@ class PluginServiceImplTest {
 | 
			
		|||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .verifyComplete();
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                FileSystemUtils.deleteRecursively(tempDir);
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                throw new RuntimeException(e);
 | 
			
		||||
            }
 | 
			
		||||
            cache.computeIfAbsent("fake-version", fakeContent)
 | 
			
		||||
                .as(StepVerifier::create)
 | 
			
		||||
                .assertNext(resource -> {
 | 
			
		||||
                    try {
 | 
			
		||||
                        assertThat(Files.exists(tempDir)).isTrue();
 | 
			
		||||
                        assertEquals(tempDir.resolve("different-version.js"),
 | 
			
		||||
                            resource.getFile().toPath());
 | 
			
		||||
                    } catch (IOException e) {
 | 
			
		||||
                        throw new RuntimeException(e);
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .verifyComplete();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Test
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue