Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A question for ReferenceConfigCache. #1293

Closed
timestatic opened this issue Jan 29, 2018 · 4 comments
Closed

A question for ReferenceConfigCache. #1293

timestatic opened this issue Jan 29, 2018 · 4 comments
Milestone

Comments

@timestatic
Copy link

timestatic commented Jan 29, 2018

官网的例子通过ReferenceConfigCache缓存ReferenceConfig实例,

ReferenceConfigCache cache = ReferenceConfigCache.getCache();  
// cache.get方法中会缓存 Reference对象,并且调用ReferenceConfig.get方法启动ReferenceConfig
XxxService xxxService = cache.get(reference);

源码中cache.get()的实现是先get, 如果== null 再put ReferenceConfig实例, 而没有提供可以由用户判断cache是否已存在的api, 我在通过groovy脚本泛化调用的时候, 需要设定当前应用与注册中心, 然后获取ReferenceConfig实例, 如下:

...
// 连接注册中心配置   
RegistryConfig registry = new RegistryConfig();   
// 注册中心协议与地址   
registry.setAddress("zookeeper://127.0.0.1:2181");    
// 当前消费者应用配置  
ApplicationConfig application = new ApplicationConfig();  
application.setName("consumer-name");   
application.setRegistry(registry);  
reference.setApplication(application);   
ReferenceConfigCache referenceConfigCache = ReferenceConfigCache.getCache(); 
GenericService genericService = referenceConfigCache.get(reference);   
// 泛化调用
genericService.$invoke(XXXX);

每一次都会把这个脚本跑一遍, 也就是每一次都会去new RegistryConfig, 和ApplicationConfig这两个实例, 虽然除了第一次以外, ReferenceConfig都是是从原有的cache中获得; 但是并没有符合这个cache工具类的原有目的. 所以ReferenceConfigCache的get()方法能否提供单独的get()方法;
还是我的使用方式不对?
非常感谢~

@chickenlj chickenlj changed the title 关于ReferenceConfigCache的问题 A question for ReferenceConfigCache. Jan 30, 2018
@chickenlj
Copy link
Contributor

Thanks for your advice, actually ReferenceConfigCache is a reference implementation for users. We highly recommend you cache any ReferenceConfig instances, and recommend you implement your own cache tools.

Anyway, the current official implementation do need improvement, we'll discuss improve it or not and how to improve it.

Welcome create a PR if you have any good ideas.

@timestatic
Copy link
Author

Thanks for your reply, I understand what you mean.

@diecui1202
Copy link

It's not a good way to provide get method for ReferenceConfigCache, we do not know the method arguments. It's also not easy-to-use.

Defer it firstly until we reach a reasonable approach.

@timestatic
Copy link
Author

timestatic commented Sep 6, 2018

In my project, this method ReferenceConfigCache is used for genericService calls, caching ReferenceConfig instances, for the user is knowing his the method arguments.Of course, it also looks complicated to use.
In my implementation, I use interfaceName, group and version as a key, used as follow:

        MyReferenceConfigCache referenceConfigCache = MyReferenceConfigCache.getCache();
        // 缓存reference实例
        GenericService genericService = referenceConfigCache.get(interfaceName, group, version);
        if (genericService == null) {
            // 引用远程服务
            ReferenceConfig<GenericService> reference = new ReferenceConfig();

            reference.setInterface(interfaceName);
            reference.setVersion(version);
            // 服务分组
            if (StringUtils.isNotBlank(group)) {
                reference.setGroup(group);
            }
            // 声明为泛化接口
            reference.setGeneric(true);

            // 连接注册中心配置
            RegistryConfig registry = new RegistryConfig();
            // 注册中心协议与地址, 根据实际修改
            registry.setAddress(registryAddress);
            // 当前消费者应用配置
            ApplicationConfig application = new ApplicationConfig();
            application.setName("consumer_name");
            application.setRegistry(registry);
            reference.setApplication(application);

            genericService = referenceConfigCache.putIfAbsentAndGet(reference);
        }

        Object result = genericService.$invoke(methodName, parameterTypes, args);

MyReferenceConfigCache some modified methodis as follows:

    public <T> T get(String interfaceName, String group, String version) {
        String key = generator.generateKey(interfaceName, group, version);

        ReferenceConfig<?> config = cache.get(key);
        if(config != null) {
            return (T) config.get();
        }

        return null;
    }

    public <T> T putIfAbsentAndGet(ReferenceConfig<T> referenceConfig) {
        String iName = referenceConfig.getInterface();
        if(StringUtils.isBlank(iName)) {
            throw new IllegalArgumentException("No interface info in ReferenceConfig" + referenceConfig);
        }

        String key = generator.generateKey(iName, referenceConfig.getGroup(), referenceConfig.getVersion());

        ReferenceConfig<?> config = cache.get(key);
        if(config != null) {
            return (T) config.get();
        }

        cache.putIfAbsent(key, referenceConfig);
        config = cache.get(key);
        return (T) config.get();
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants