Hi, Asaf. Maybe? > > client.update(ConnectionInfo.builder() > .setServiceUrl() > .set...() > .build())
Yes, This is clearer. Thanks, Baodi Shi 在 2023年2月7日 23:48:03 上,Asaf Mesika <asaf.mes...@gmail.com> 写道: > Oh, thanks Baodi - now I understand what he meant by "calling rebuild". > I agree, it's not very intuitive. > > Maybe? > > client.update(ConnectionInfo.builder() > .setServiceUrl() > .set...() > .build()) > > > On Mon, Feb 6, 2023 at 2:39 AM Baodi Shi <ba...@apache.org> wrote: > > I thought about it for a moment, and this is not a good idea. > > > Using newBuild may be understood by the user as recreating the client > > object. It is still intuitive to add the `updateXXX` method. > > > > Thanks, > > Baodi Shi > > > > 在 2023年2月5日 23:01:57 上,Asaf Mesika <asaf.mes...@gmail.com> 写道: > > > > Can you please write rebuild example? > > > > > > On Sun, Feb 5, 2023 at 4:05 PM Baodi Shi <ba...@apache.org> wrote: > > > > > > > > > > > > > > Not completely different IMO. When we want to update the service URL, > > > > > > > > > > > > > > we usually want to connect to another cluster. However, the cluster > > > > > > > > > > > > > > could have configured authentication, TLS for security, but we cannot > > > > > > > > > > > > > > guarantee two clusters share the same TLS certificates or > > > > > > > > > > > > > > authentication configs. I think we should group these necessary > > > > > > > > > > > > > > information into a common class like `ConnectInfo`. Then, just expose > > > > > > > > > > > > > > a method to update the `ConnectInfo` so that code could be more > > > > > > > > > > > > > > scalable. > > > > > > > > > > > > > > > > > > > > It makes sense to me. > > > > > > > > > Alternatively, can we directly support rebuilding PulsarClient? > > > > > > > > > PulsarClient client = PulsarClient.builder() > > > > > > .serviceUrl("old url") > > > > > > .tlsTrustCertsFilePath() > > > > > > .statsInterval(1, TimeUnit.SECONDS) > > > > > > .build(); > > > > > > > > > client.newBuilder() > > > > > > .serviceUrl("new url") > > > > > > // tls relate > > > > > > .tlsTrustCertsFilePath() > > > > > > .statsInterval(2, TimeUnit.SECONDS) > > > > > > .build(); > > > > > > > > > > > > When calling rebuild, the new configuration overwrites the old > > > > > > configuration, and if there are no settings, the old configuration is > > used. > > > > > > > > > 在 2023年2月2日 23:02:21 上,Asaf Mesika <asaf.mes...@gmail.com> 写道: > > > > > > > > > > Ok, makes sense. > > > > > > > > > > > > > > > > > > > > > On Thu, Feb 2, 2023 at 4:02 PM Yunze Xu <y...@streamnative.io.invalid> > > > > > > > wrote: > > > > > > > > > > > > > > Not completely different IMO. When we want to update the service URL, > > > > > > > > > > > > > > we usually want to connect to another cluster. However, the cluster > > > > > > > > > > > > > > could have configured authentication, TLS for security, but we cannot > > > > > > > > > > > > > > guarantee two clusters share the same TLS certificates or > > > > > > > > > > > > > > authentication configs. I think we should group these necessary > > > > > > > > > > > > > > information into a common class like `ConnectInfo`. Then, just expose > > > > > > > > > > > > > > a method to update the `ConnectInfo` so that code could be more > > > > > > > > > > > > > > scalable. > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > Yunze > > > > > > > > > > > > > > > > > > > > > On Thu, Feb 2, 2023 at 9:39 PM Asaf Mesika <asaf.mes...@gmail.com> > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Ok, the last two methods IMO are a completely different topic. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > I wonder what the maintainers think about this. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Mon, Jan 30, 2023 at 4:16 AM Yunze Xu > > <y...@streamnative.io.invalid > > > > > > > > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > In summary, the core issue is that ServiceUrlProvider could be > > > > > > > > > > > > > > > > misused. A user might want to implement its own ServiceUrlProvider > > by > > > > > > > > > > > > > > > > changing the returned value of `get` method but it actually does > > not > > > > > > > > > > > > > > > > work. The built-in implementations like AutoFailover actually work > > by > > > > > > > > > > > > > > > > these `updateXXX` methods. So it's meaningless to provide them as > > > > > > > > > > > > > > > > ServiceUrlProvider implementations. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > To answer your question directly: totally yes. But not only > > > > > > > > > > > > > > > > `setServiceUrl` (the name is `updateServiceUrl` in code), the > > > > > > > > > > > > > > > > `updateAuthentication` and `updateTlsTrustCertsFilePath` methods, > > > > > > > > > > > > > > > > which are not exposed to `PulsarClient`, should also be exposed. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > Yunze > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Sun, Jan 29, 2023 at 11:57 PM Asaf Mesika < > > asaf.mes...@gmail.com> > > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Yunze - in summary - your proposal is to get rid of the > > > > > > > > > > > > > > > > ServiceUrlProvider > > > > > > > > > > > > > > > > > right? You just want to have setServiceUrl on the client instead? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Wed, Jan 25, 2023 at 2:03 PM Yunze Xu > > > > > > > > > > > > > > <y...@streamnative.io.invalid> > > > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > It makes sense to me. So the better way is still providing the > > > > > > > > > > > > > > > > > > `updateXXX` methods to `PulsarClient`. As for how to detect the > > > > > > > > > > > > > > > > > > connection info (e.g. service URL) changes, it's determined by > > > > > > the > > > > > > > > > > > > > > > > > > user's implementation. For example, the current > > > > > > AutoClusterFailover > > > > > > > > > > > > > > > > > > polls with a fixed interval. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > We can also implement a notification mechanism based on the > > > > > > > > > > > > > > > > > > `updateXXX` methods. For example, assuming we have a producer > > > > > > that > > > > > > > > > > > > > > > > > > writes the latest service URL to a topic and a consumer that > > > > > > reads > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > > > > latest service URL from that topic. Then, the consumer could > > call > > > > > > > > > > > > > > > > > > `pulsarClient.updateXXX` once it receives the latest service > > URL. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > Yunze > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Tue, Jan 24, 2023 at 4:32 PM Asaf Mesika < > > > > > > asaf.mes...@gmail.com > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > If I understand correctly, the idea of having the ability to > > > > > > > > > > > > > > change > > > > > > > > > > > > > > > > > > > serviceUrl is to support switching over between clusters > > > > > > > > > > > > > > dynamically? > > > > > > > > > > > > > > > > > > > If that is the case, doesn't it make sense that it will > > trigger > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > > > > change > > > > > > > > > > > > > > > > > > > to the client instead of the client polling it and check it > > > > > > self > > > > > > > > > > > > > > if > > > > > > > > > > > > > > > > > > > something has changed? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Mon, Jan 23, 2023 at 5:00 AM Yunze Xu > > > > > > > > > > > > > > > > <y...@streamnative.io.invalid> > > > > > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Yes. The poll happens in the client's internal thread. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > > > Yunze > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Sun, Jan 22, 2023 at 6:56 PM Asaf Mesika < > > > > > > > > > > > > > > asaf.mes...@gmail.com > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > and the client will poll the ConnectInfoProvider and > > check > > > > > > if > > > > > > > > > > > > > > > > > > something > > > > > > > > > > > > > > > > > > > > was > > > > > > > > > > > > > > > > > > > > > changed? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Fri, Jan 20, 2023 at 11:19 AM Yunze Xu > > > > > > > > > > > > > > > > > > <y...@streamnative.io.invalid> > > > > > > > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > I think the `updateServiceUrl` is not the initial > > > > > > > > > > > > > > purpose of > > > > > > > > > > > > > > > > > > > > exposing to > > > > > > > > > > > > > > > > > > > > > > the Client API. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > I agree. We might need an API like > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ```java > > > > > > > > > > > > > > > > > > > > > > ClientBuilder serviceUrlProvider(ServiceUrlProvider > > > > > > > > > > > > > > > > > > > > > > serviceUrlProvider, Duration interval) > > > > > > > > > > > > > > > > > > > > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > But not only the service URL, as you can see, the > > > > > > > > > > > > > > > > > > > > > > `AutoClusterFailover` implementation is already beyond > > > > > > the > > > > > > > > > > > > > > > > scope of > > > > > > > > > > > > > > > > > > > > > > service URL, it uses two internal APIs > > > > > > > > > > > > > > `updateAuthentication` > > > > > > > > > > > > > > > > and > > > > > > > > > > > > > > > > > > > > > > `updateTlsTrustCertsFilePath` to update other states of > > > > > > > > > > > > > > > > > > > > > > PulsarClientImpl. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > So from the user's perspective, they only need to > > > > > > apply > > > > > > > > > > > > > > a > > > > > > > > > > > > > > > > > > service > > > > > > > > > > > > > > > > > > > > URL > > > > > > > > > > > > > > > > > > > > > > provided to the client > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Yes. That's when I thought of when I saw the C++ client > > > > > > > > > > > > > > catch > > > > > > > > > > > > > > > > up > > > > > > > > > > > > > > > > > > [1]. > > > > > > > > > > > > > > > > > > > > > > The `initialize` and `close` methods are not necessary. > > > > > > If > > > > > > > > > > > > > > let > > > > > > > > > > > > > > > > me > > > > > > > > > > > > > > > > > > > > > > design the interface, I would like the following > > > > > > solution, > > > > > > > > > > > > > > > > which is > > > > > > > > > > > > > > > > > > > > > > more simple and can accept a lambda. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ```java > > > > > > > > > > > > > > > > > > > > > > public interface ServiceUrlProvider { > > > > > > > > > > > > > > > > > > > > > > String getServiceUrl(); > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > However, as I've mentioned again, now authentication > > and > > > > > > > > > > > > > > TLS > > > > > > > > > > > > > > > > info > > > > > > > > > > > > > > > > > > also > > > > > > > > > > > > > > > > > > > > > > need updates, so I have an initial design like: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ```java > > > > > > > > > > > > > > > > > > > > > > public class ConnectInfo { > > > > > > > > > > > > > > > > > > > > > > String serviceUrl; > > > > > > > > > > > > > > > > > > > > > > Authentication authentication; > > > > > > > > > > > > > > > > > > > > > > String tlsCertificatesFile; > > > > > > > > > > > > > > > > > > > > > > // ... > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > interface ConnectInfoProvider extends > > > > > > > > > > > > > > Supplier<ConnectInfo> { > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > When configuring the `ConnectInfoProvider`, we should > > > > > > > > > > > > > > provide > > > > > > > > > > > > > > > > an > > > > > > > > > > > > > > > > > > > > interval. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > And I'm going to open a PIP for it to deprecate > > > > > > > > > > > > > > > > > > `ServiceUrlProvider`. > > > > > > > > > > > > > > > > > > > > > > BTW, I found this issue when I reviewed the PR to > > migrate > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > > > > > > > > ServiceUrlProvider into C++ client. IMO, the current > > > > > > > > > > > > > > design in > > > > > > > > > > > > > > > > Java > > > > > > > > > > > > > > > > > > > > > > client is bad and I don't want to adopt the same design > > > > > > in > > > > > > > > > > > > > > C++ > > > > > > > > > > > > > > > > > > client. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > > > > > Yunze > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Thu, Jan 19, 2023 at 4:51 PM PengHui Li < > > > > > > > > > > > > > > peng...@apache.org > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Is it better to introduce a service URL detect > > interval > > > > > > > > > > > > > > to > > > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > > > > > > service > > > > > > > > > > > > > > > > > > > > > > URL > > > > > > > > > > > > > > > > > > > > > > > provider? > > > > > > > > > > > > > > > > > > > > > > > I think the `updateServiceUrl` is not the initial > > > > > > > > > > > > > > purpose of > > > > > > > > > > > > > > > > > > > > exposing to > > > > > > > > > > > > > > > > > > > > > > > the Client API. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > It looks like users just provide the interval of > > > > > > checking > > > > > > > > > > > > > > > > > > whether the > > > > > > > > > > > > > > > > > > > > > > > service URL is changed. > > > > > > > > > > > > > > > > > > > > > > > The Pulsar client will check it automatically. Using > > > > > > > > > > > > > > > > > > > > updateServiceUrl can > > > > > > > > > > > > > > > > > > > > > > > also achieve the purpose, > > > > > > > > > > > > > > > > > > > > > > > but users need to provide a fake service URL first or > > > > > > > > > > > > > > fetch > > > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > > > > > > service > > > > > > > > > > > > > > > > > > > > > > URL > > > > > > > > > > > > > > > > > > > > > > > before > > > > > > > > > > > > > > > > > > > > > > > creating the client. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Another reason we need service URL provider API is > > that > > > > > > > > > > > > > > one > > > > > > > > > > > > > > > > team > > > > > > > > > > > > > > > > > > will > > > > > > > > > > > > > > > > > > > > > > > usually > > > > > > > > > > > > > > > > > > > > > > > provide an extra pulsar client lib with the service > > URL > > > > > > > > > > > > > > > > provider > > > > > > > > > > > > > > > > > > > > > > > implementation. > > > > > > > > > > > > > > > > > > > > > > > The lib > > > > > > > > > > > > > > > > > > > > > > > can be used across multiple teams. So from the user's > > > > > > > > > > > > > > > > > > perspective, > > > > > > > > > > > > > > > > > > > > they > > > > > > > > > > > > > > > > > > > > > > > only need to apply > > > > > > > > > > > > > > > > > > > > > > > a service URL provided to the client, they don't care > > > > > > > > > > > > > > about > > > > > > > > > > > > > > > > what > > > > > > > > > > > > > > > > > > is > > > > > > > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > > > > > > > > > service URL and how to > > > > > > > > > > > > > > > > > > > > > > > update it. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > > > > > > Penghui > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > On Thu, Jan 19, 2023 at 3:43 PM Baodi Shi < > > > > > > > > > > > > > > ba...@apache.org> > > > > > > > > > > > > > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Hi, Yunze: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Obviously, the `ServiceUrlProvider` config is > > > > > > > > > > > > > > redundant. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Agree. In fact, The client already provides the > > > > > > > > > > > > > > > > > > updateServiceUrl > > > > > > > > > > > > > > > > > > > > > > method, > > > > > > > > > > > > > > > > > > > > > > > > which the user can use to implement a dynamic > > update > > > > > > > > > > > > > > > > service > > > > > > > > > > > > > > > > > > URL. > > > > > > > > > > > > > > > > > > > > As > > > > > > > > > > > > > > > > > > > > > > for > > > > > > > > > > > > > > > > > > > > > > > > how the user implements it and how to close his > > > > > > > > > > > > > > resources, > > > > > > > > > > > > > > > > I > > > > > > > > > > > > > > > > > > think > > > > > > > > > > > > > > > > > > > > it > > > > > > > > > > > > > > > > > > > > > > can > > > > > > > > > > > > > > > > > > > > > > > > be left to the user. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 在 2023年1月19日 15:16:52 上,Yunze Xu > > > > > > > > > > > > > > > > <y...@streamnative.io.invalid > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 写道: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Hi all, > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Currently we have a `ServiceUrlProvider` > > interface > > > > > > to > > > > > > > > > > > > > > > > > > configure > > > > > > > > > > > > > > > > > > > > when > > > > > > > > > > > > > > > > > > > > > > > > > constructing a PulsarClient in > > > > > > > > > > > > > > > > > > > > `ClientBuilder#serviceUrlProvider`. > > > > > > > > > > > > > > > > > > > > > > > > > From the beginning, I thought the `getServiceUrl` > > > > > > > > > > > > > > method > > > > > > > > > > > > > > > > is > > > > > > > > > > > > > > > > > > > > called > > > > > > > > > > > > > > > > > > > > > > > > > each time the service URL is used, e.g. topic > > > > > > > > > > > > > > metadata > > > > > > > > > > > > > > > > > > lookup. > > > > > > > > > > > > > > > > > > > > > > > > > However, the `getServiceUrl` method is only > > called > > > > > > > > > > > > > > when > > > > > > > > > > > > > > > > > > > > constructing > > > > > > > > > > > > > > > > > > > > > > > > > the PulsarClient object. To update the > > > > > > PulsarClient's > > > > > > > > > > > > > > > > > > internal > > > > > > > > > > > > > > > > > > > > > > service > > > > > > > > > > > > > > > > > > > > > > > > > URL, `PulsarClient#updateServiceUrl` must be > > > > > > called. > > > > > > > > > > > > > > > > > > Therefore, > > > > > > > > > > > > > > > > > > > > if we > > > > > > > > > > > > > > > > > > > > > > > > > want to implement a `ServiceUrlProvider` that > > > > > > > > > > > > > > retrieves > > > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > > > > > > latest > > > > > > > > > > > > > > > > > > > > > > > > > service URL from a database, I have to implement > > it > > > > > > > > > > > > > > like: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ```java > > > > > > > > > > > > > > > > > > > > > > > > > class DataBaseServiceUrlProvider implements > > > > > > > > > > > > > > > > > > ServiceUrlProvider { > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > private final ScheduledExecutorService > > executor > > > > > > = > > > > > > > > > > > > > > > > > > > > > > > > > Executors.newSingleThreadScheduledExecutor(); > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > @Override > > > > > > > > > > > > > > > > > > > > > > > > > public void initialize(PulsarClient client) { > > > > > > > > > > > > > > > > > > > > > > > > > executor.schedule(() -> { > > > > > > > > > > > > > > > > > > > > > > > > > try { > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > client.updateServiceUrl(readServiceUrlFromDB()/* a > > > > > > > > > > > > > > > > > > > > > > > > > fake method */); > > > > > > > > > > > > > > > > > > > > > > > > > } catch (PulsarClientException e) { > > > > > > > > > > > > > > > > > > > > > > > > > throw new RuntimeException(e); > > > > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > }, 1, TimeUnit.SECONDS); > > > > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > @Override > > > > > > > > > > > > > > > > > > > > > > > > > public String getServiceUrl() { > > > > > > > > > > > > > > > > > > > > > > > > > return "pulsar://localhost:6650"; > > > > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > @Override > > > > > > > > > > > > > > > > > > > > > > > > > public void close() { > > > > > > > > > > > > > > > > > > > > > > > > > executor.shutdown(); > > > > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > The key point is, if we didn't call > > > > > > > > > > > > > > > > > > `client.updateServiceUrl` and > > > > > > > > > > > > > > > > > > > > > > only > > > > > > > > > > > > > > > > > > > > > > > > > modified the returned value of `getServiceUrl` > > > > > > > > > > > > > > > > periodically, > > > > > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > > > > > > > > > > > internal service URL would never be updated. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Based on the provider above, the following two > > code > > > > > > > > > > > > > > > > snippets > > > > > > > > > > > > > > > > > > > > could be > > > > > > > > > > > > > > > > > > > > > > > > > nearly the same. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ```java > > > > > > > > > > > > > > > > > > > > > > > > > var client = > > > > > > > > > > > > > > > > PulsarClient.builder().serviceUrlProvider(new > > > > > > > > > > > > > > > > > > > > > > > > > DataBaseServiceUrlProvider()).build(); > > > > > > > > > > > > > > > > > > > > > > > > > /* ... */ > > > > > > > > > > > > > > > > > > > > > > > > > client.close(); > > > > > > > > > > > > > > > > > > > > > > > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > ```java > > > > > > > > > > > > > > > > > > > > > > > > > var client = > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > PulsarClient.builder().serviceUrl("pulsar://localhost:6650").build(); > > > > > > > > > > > > > > > > > > > > > > > > > var provider = new DataBaseServiceUrlProvider(); > > > > > > > > > > > > > > > > > > > > > > > > > provider.initialize(client); > > > > > > > > > > > > > > > > > > > > > > > > > /* ... */ > > > > > > > > > > > > > > > > > > > > > > > > > provider.close(); > > > > > > > > > > > > > > > > > > > > > > > > > client.close(); > > > > > > > > > > > > > > > > > > > > > > > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Obviously, the `ServiceUrlProvider` config is > > > > > > > > > > > > > > redundant. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > PIP-121 implements the `AutoClusterFailover` as > > the > > > > > > > > > > > > > > > > service > > > > > > > > > > > > > > > > > > URL > > > > > > > > > > > > > > > > > > > > > > > > > provider. However, it also calls the following > > > > > > > > > > > > > > methods > > > > > > > > > > > > > > > > > > > > periodically: > > > > > > > > > > > > > > > > > > > > > > > > > - PulsarClientImpl#updateAuthentication > > > > > > > > > > > > > > > > > > > > > > > > > - PulsarClientImpl#updateTlsTrustCertsFilePath > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > It's unnatural and intuitive to say a service URL > > > > > > > > > > > > > > > > provider > > > > > > > > > > > > > > > > > > could > > > > > > > > > > > > > > > > > > > > > > > > > modify the internal states of `PulsarClient`, > > > > > > > > > > > > > > including: > > > > > > > > > > > > > > > > > > > > > > > > > - the service URL > > > > > > > > > > > > > > > > > > > > > > > > > - the authentication > > > > > > > > > > > > > > > > > > > > > > > > > - the TLS trust certificate file > > > > > > > > > > > > > > > > > > > > > > > > > - ... > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > BTW, the implementation of PIP-121 [1] is > > different > > > > > > > > > > > > > > from > > > > > > > > > > > > > > > > the > > > > > > > > > > > > > > > > > > > > design > > > > > > > > > > > > > > > > > > > > > > [2]. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > [1] https://github.com/apache/pulsar/pull/13316 > > > > > > > > > > > > > > > > > > > > > > > > > [2] > > https://github.com/apache/pulsar/issues/13315 > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thanks, > > > > > > > > > > > > > > > > > > > > > > > > > Yunze > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >