package com.vincent.rsf.server.manager.service.impl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.Duration; import java.util.Arrays; @Slf4j @Service @RequiredArgsConstructor public class WmsRedisLuaService { private static final DefaultRedisScript LOCATION_CLAIM_SCRIPT = createScript("wms-lua/location-claim.lua"); private static final DefaultRedisScript INVENTORY_RESERVE_SCRIPT = createScript("wms-lua/inventory-reserve.lua"); private final StringRedisTemplate redisTemplate; public boolean claimLocation(String occupyKey, String taskKey, String mode, String occupyValue, String taskValue, Duration ttl) { Long result = redisTemplate.execute( LOCATION_CLAIM_SCRIPT, Arrays.asList(occupyKey, taskKey), mode, occupyValue, taskValue, String.valueOf(ttl.toMillis()) ); return result != null && result > 0; } public boolean reserveInventory(String inventoryKey, String orderKey, BigDecimal initialAvailable, BigDecimal reserveQuantity, Duration ttl) { Long result = redisTemplate.execute( INVENTORY_RESERVE_SCRIPT, Arrays.asList(inventoryKey, orderKey), initialAvailable.toPlainString(), reserveQuantity.toPlainString(), String.valueOf(ttl.toMillis()) ); return result != null && result > 0; } public void releaseKeys(String... keys) { if (keys == null || keys.length == 0) { return; } try { redisTemplate.delete(Arrays.asList(keys)); } catch (Exception ex) { log.warn("Release redis keys failed", ex); } } public void resetInventoryCache(String inventoryKey, BigDecimal availableQuantity, Duration ttl) { redisTemplate.opsForValue().set(inventoryKey, availableQuantity.toPlainString(), ttl); } private static DefaultRedisScript createScript(String path) { DefaultRedisScript script = new DefaultRedisScript<>(); script.setLocation(new ClassPathResource(path)); script.setResultType(Long.class); return script; } }