aop - Threads mislead the aspect's point cut logic - Stack Overflow

We have the following requirement in our micro-service architecture: Calling some of A's microserv

We have the following requirement in our micro-service architecture: Calling some of A's microservice endpoints should block calling endpoints of B's microservice. To accomplish this we have created two annotations and global lock. Used language is Java, the framework - Spring aspects.

First annotation is used to mark the method that obtains the lock.

@Around("@annotation(com.example.distributed.lock.LockWith)")
Object LockWithAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
  lock.aquire();
  ...
  proceed = joinPoint.proceed();
  ...
  lock.release();
}

Second is used to check if lock exist and continue if lock doesn't exist.

@Around("@annotation(com.example.distributed.lock.GuardedBy)")
Object guardedByAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
  // ... 
  if (lock.notExist) {
    return joinPoint.proceed();
  }
  thrwo new DistributedLockException("Lock exist!");
}

With this solution we have a problem, if someone decides not to block and wait for the long running operation but separate it in a thread e.g.

@LockWith(name=...)
public void lockUserForMaintenance(String userName) {
  ...
  // ERROR: Lock is released before the real job is done!
  new Thread(() -> {
     // do some long running job
  });
  ...
}

Organizing solution in this way we release the lock earlier which is a problem.

Is it possible to track this use case? ... or to forbid it somehow?

Any suggestions will be helpful. Thank you in advance!

We have the following requirement in our micro-service architecture: Calling some of A's microservice endpoints should block calling endpoints of B's microservice. To accomplish this we have created two annotations and global lock. Used language is Java, the framework - Spring aspects.

First annotation is used to mark the method that obtains the lock.

@Around("@annotation(com.example.distributed.lock.LockWith)")
Object LockWithAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
  lock.aquire();
  ...
  proceed = joinPoint.proceed();
  ...
  lock.release();
}

Second is used to check if lock exist and continue if lock doesn't exist.

@Around("@annotation(com.example.distributed.lock.GuardedBy)")
Object guardedByAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
  // ... 
  if (lock.notExist) {
    return joinPoint.proceed();
  }
  thrwo new DistributedLockException("Lock exist!");
}

With this solution we have a problem, if someone decides not to block and wait for the long running operation but separate it in a thread e.g.

@LockWith(name=...)
public void lockUserForMaintenance(String userName) {
  ...
  // ERROR: Lock is released before the real job is done!
  new Thread(() -> {
     // do some long running job
  });
  ...
}

Organizing solution in this way we release the lock earlier which is a problem.

Is it possible to track this use case? ... or to forbid it somehow?

Any suggestions will be helpful. Thank you in advance!

Share Improve this question edited Mar 11 at 15:26 zashto asked Mar 11 at 15:17 zashtozashto 134 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

This result is to be expected, as both Spring AOP and native AspectJ advice methods are always executed in the same thread as their intercepted joinpoints. IMO, you are using the wrong approach to solve your problem. In native AspectJ, you could declare a compiler warning or error when in an annotated method e.g. a Thread constructor is called. But that would not solve all problems. Imagine a developer using thread pools with pre-existing threads.

Basically, you want to do the opposite of the other developer: The latter wants to use concurrency while you wish to synchronise on the end of the spawned thread. Besides, depending on what the thread does it might not even be a problem prohibiting the other service to be called.

The best you can do is to perform proper code reviews and establish team conventions, if you wish to continue this practice with AOP being responsible for creating and releasing global locks. You also might want to explore using Java's structured concurrency features, in preview since JDK 21, refined in subsequent previews for 22 to 24. But that would also require team conventions to actually use the feature when necessary.

IMO, you probably have a design problem here. If microservices depend on each other so strongly in this way, probably the services' APIs are structured the wrong way regarding separation of concerns. Microservices are meant to be independent of each other and the calls stateless. You ought to refactor to avoid this situation being a problem in the first place. The global lock is a design smell, if I may say so.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744785486a4593597.html

相关推荐

  • aop - Threads mislead the aspect's point cut logic - Stack Overflow

    We have the following requirement in our micro-service architecture: Calling some of A's microserv

    15小时前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信