Web Service síncrono

Tenho um WebService RESTful desenvolvido em Java.

Preciso que um método(serviço) seja síncrono. Nas não posso fazer isso do lado do cliente, tem que ser feito do lado do WebService, pois este serviço só pode ser requisitado uma única vez por vez. Outra aplicação só pode requisitar o método(serviço) se ele não estiver em execução.

Como posso fazer isso do lado do WebService?

Bom dia Rodrigo

Eu não entendi ai a idéia.
Todo método REST por padrão é SINCRONO…então seu texto ficou sem sentido…

Pelo que eu entendi, você quer que o método seja thread-safe. Não síncrono no sentido de sync/async, mas no sentido de ser serial, acessado apenas por uma thread por vez!

Os webservices JAX-RS são multi-threaded por natureza. A primeira coisa que me vem na cabeça é encapsular o teu método em um bean singleton, e tratar a questão de acesso serial lá dentro com mutex ou alguma estrutura de dados, como por exemplo as que implementam essa interface: BlockingQueue. O métodono webservice vai chamar o método dentro do singleton e lá você faz o “gargalo”.

Acho que é isso!

EDIT: Respondi pensando em atender todas as requisições de forma enfileirada. Caso você queira, também dá para fazer de um jeito que quando alguém invoca o serviço e o mesmo está ocupado, um erro seja retornado. A ideia é que você implemente o controle de acesso e, por exemplo, um método isRunning() ou isBusy(). Você chama esse método antes de executar o método que deve ser chamado de forma serial e, caso esteja ocupado, você retorna um erro pro cliente.

Se eu colocar no método o synchronized vai dar certo?

@Rodrigo1895, não existe solução simples para o que detalhou, você terá que desenvolver a lógica de resposta para cada requisição conforme o @lvlbarbosa já comentou.

Nunca tentei, mas provavelmente “synchronized” não será aceito no método. Mas mesmo que seja você não deve pensar desta forma, você deve receber a requisição e retornar uma mensagem imediatamente, se você começar a bloquear os métodos de requisição de um webservice você poderá estourar o limite de threads do seu servidor web e apresentar problemas em outros lugares.

Agora entendi…kkkkk
Cara…seu EndPoint REST tem que ser SINGLETON + SYNCHRONIZED no server que vai dar certo!
Vc vai deixar uma seu ENDPOINT MONO…respondendo 1 requisição por vez…

FernandoFranzini, poderia me dar um exemplo bem simples de como fazer um método assim?

Isso depende do seu provider de REST. Cada um faz isso de uma forma diferente Rodrigo.

Eu utilizo o Jersey. Por exemplo este método abaixo, como posso fazer com que ele tenha uma requisição por vez:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/teste")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public class Teste {

	@GET
	@Path("/testando/{teste}")
	public String get(@PathParam("teste") String teste) {
		System.out.println(teste);
		return "OK";
	}
}
  1. Segundo a documentação, use @Singleton na classe - https://jersey.java.net/documentation/latest/user-guide.html#d0e2642

  2. coloque o método como sincronizado public synchronized String get(@PathParam(“teste”) String teste) e voila…Esta ai seu REST MONO…

Vc tem certeza que fazer isso? Deixar seu rest mono?
Qual a natureza do seu problema?

Então, estou fazendo um aplicação Android para os funcionários de distribuidoras que separam os produtos dos pedidos.

Acontece que quando um funcionário faz uma requisição para separar um pedido, apenas ele pode separar aquele pedido, então nenhum outro funcionário tem acesso à aquele pedido.
E pode ocorrer de mais de um funcionário requisitar o mesmo pedido ao mesmo tempo…

Então esta parte de requisitar o pedido queria que tivesse apenas uma requisição por vez.

Já pensou em utilizar os Locks do JPA? Acho que te serviria melhor.

Então Rodrigo, foi exatamente oque eu pensei…
Bom, vou te dar minha opinião, vc fica na liberdade ai para fazer oque achar melhor:

Vc esta claramente adotando a solução errada. Porque?

  1. Vc esta deixando seu serviço mono. Isso é inaceitável! A performance vai ser horrível! kkkk Vc vai fazer os outros pagarem por causa de um “se”?. Se em 200 request simultâneo, vc ira atender 1 por vez só por causa de um “se talvez dois fizerem o mesmo pedido”? Se porventura cada resquest demorar 2 segundos de processamento, o ultimo em 200 vai ter que esperar quase 7 minutos para ser atendido…realmente é ago impraticável.

  2. Seu problema é questão de negocio e não de infra-estrutura. Vc esta endereçando na infra para resolver um problema de negocio, fora que esta destruindo um das maiores benefícios de soluções web que é atender requisições simultâneas.

  3. Seu problema é de negocio e vc tem que resolver no negocio! Vc tem que idealizar alguma logica na sua solução que identifique que duas requisições estão no mesmo pedido e tratar isso adequadamente e não bloquear multiprocessamento do seu web services. Existem várias formas para se fazer isso, seu caso ta cheirando bloqueio otimista. Deixe seu web services receber e tratar múltiplos clientes e implemente essa logica de consistência no seus objetos!

Boa sorte! :slight_smile: