This is my Spring bean in the configuration class that creates a gRPC ManagedChannel:
@Configuration public class CockroachDbConfig { @Bean public ManagedChannel getManagedChannel() { return ManagedChannelBuilder.forTarget(CR_GRPC_SERVER) .usePlaintext() .build(); } }
The controller method is provided below:
@RestController public class DBProxyController { @Autowired private DBProxyService dbProxyService; @RequestMapping(value = "/", method = RequestMethod.POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE ) @SuppressWarnings("BlockingMethodInNonBlockingContext") public Mono<Void> handleRequest(@RequestBody String requestBody, ServerHttpResponse serverHttpResponse, ServerHttpRequest request) { org.springframework.http.HttpHeaders headers = request.getHeaders(); Map<String, String> responseMap = dbProxyService.processRequest(requestBody, headers); String response = responseMap.get(X_AMZN_RESPONSE); if (response.equalsIgnoreCase("{}")) { LOGGER.info("We are ot able to sucessfully process the request and reutning an empty response"); } return serverHttpResponse.writeWith(strToDataBuffer(response)); } }
The service class is:
@Service public class DBProxyService { public Map<String, String> processRequest(final String requestBody, final org.springframework.http.HttpHeaders headers) { ManagedChannel customManagedChannel = (new CockroachDbConfig()).getManagedChannel(); switch (action) { case GETITEM: { // some code ProtoService.shutdownManagedChannel(customManagedChannel); } case PUTITEM: { // some code ProtoService.shutdownManagedChannel(customManagedChannel); } } } }
For each request, I create a new ManagedChannel
in the service method processRequest
and shut it down using the method called shutdownManagedChannel
.
Earlier, I try to use the @Autowired
for the managed channel as below:
@Service public class DBProxyService { @Autowired private ManagedChannel customManagedChannel; public Map<String, String> processRequest(final String requestBody, final org.springframework.http.HttpHeaders headers) { switch (action) { case GETITEM: { // some code ProtoService.shutdownManagedChannel(customManagedChannel); } case PUTITEM: { // some code ProtoService.shutdownManagedChannel(customManagedChannel); } } } }
This was not successful as I shut down the channel after the completion of each request and I guess need to figure out a way to re-initialize the bean for each call.
So, how to I re-initialize the ManagedChannel
for each request when the app is running?
Thanks.
Advertisement
Answer
A simple solution, not relying too much on the framework would be to inject a bean of type Supplier<ManagedChannel>
(or any other functional interface type that works for your use case).
@Bean public Suuplier<ManagedChannel> getManagedChannel() { return () -> ManagedChannelBuilder.forTarget(CR_GRPC_SERVER) .usePlaintext() .build(); }
And then use the get
method to re-instantiate a new channel whenever you need it.
Otherwise, you could work with the scope Prototype
that recreates the bean in some circumstances instead of treating it as a singleton (documentation). Be aware that injecting prototype beans in singleton beans require you to do some configuration gymnastic, as stated in the point 1.5.3 of the documentation.