#
zhou zhou
昨天 c1c045cad0f39a38409de117e9ddf470804b0d81
#
5个文件已添加
1个文件已修改
146 ■■■■■ 已修改文件
rsf-server/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisConstants.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisKeys.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WmsRedisLuaService.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/wms-lua/inventory-reserve.lua 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/wms-lua/location-claim.lua 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/pom.xml
@@ -46,6 +46,10 @@
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisConstants.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.common.redis;
public final class RedisConstants {
    private RedisConstants() {
    }
    public static final String LUA_MODE_PUTAWAY = "PUTAWAY";
    public static final String LUA_MODE_PICK = "PICK";
}
rsf-server/src/main/java/com/vincent/rsf/server/common/redis/RedisKeys.java
New file
@@ -0,0 +1,23 @@
package com.vincent.rsf.server.common.redis;
public final class RedisKeys {
    private RedisKeys() {
    }
    public static String locationOccupy(Long locationId) {
        return "wms:location:occupy:" + locationId;
    }
    public static String locationTaskOccupy(Long locationId) {
        return "wms:task:occupy:location:" + locationId;
    }
    public static String stockAvailable(Long inventoryId) {
        return "wms:stock:available:" + inventoryId;
    }
    public static String stockReserve(String orderNo) {
        return "wms:stock:reserve:" + orderNo;
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WmsRedisLuaService.java
New file
@@ -0,0 +1,68 @@
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<Long> LOCATION_CLAIM_SCRIPT = createScript("wms-lua/location-claim.lua");
    private static final DefaultRedisScript<Long> 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<Long> createScript(String path) {
        DefaultRedisScript<Long> script = new DefaultRedisScript<>();
        script.setLocation(new ClassPathResource(path));
        script.setResultType(Long.class);
        return script;
    }
}
rsf-server/src/main/resources/wms-lua/inventory-reserve.lua
New file
@@ -0,0 +1,20 @@
local current = redis.call('get', KEYS[1])
local initial = tonumber(ARGV[1])
local reserve = tonumber(ARGV[2])
local ttl = tonumber(ARGV[3])
if current == false then
  current = initial
else
  current = tonumber(current)
end
if current < reserve then
  return 0
end
local nextValue = current - reserve
redis.call('psetex', KEYS[1], ttl, tostring(nextValue))
redis.call('incrbyfloat', KEYS[2], reserve)
redis.call('pexpire', KEYS[2], ttl)
return 1
rsf-server/src/main/resources/wms-lua/location-claim.lua
New file
@@ -0,0 +1,19 @@
local mode = ARGV[1]
local occupyValue = ARGV[2]
local taskValue = ARGV[3]
local ttl = tonumber(ARGV[4])
if mode == 'PUTAWAY' then
  if redis.call('exists', KEYS[1]) == 1 or redis.call('exists', KEYS[2]) == 1 then
    return 0
  end
  redis.call('psetex', KEYS[1], ttl, occupyValue)
  redis.call('psetex', KEYS[2], ttl, taskValue)
  return 1
end
if redis.call('exists', KEYS[2]) == 1 then
  return 0
end
redis.call('psetex', KEYS[2], ttl, taskValue)
return 1