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.
CodePudding user response:
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.