[ 
https://issues.apache.org/jira/browse/SLING-10030?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17266884#comment-17266884
 ] 

Tomás Dias Almeida commented on SLING-10030:
--------------------------------------------

Proposed PR: 
https://github.com/apache/sling-org-apache-sling-servlets-post/pull/10

> Add an optional ranking as a property for PostOperation implementation 
> -----------------------------------------------------------------------
>
>                 Key: SLING-10030
>                 URL: https://issues.apache.org/jira/browse/SLING-10030
>             Project: Sling
>          Issue Type: Improvement
>    Affects Versions: Servlets Post 2.3.36
>            Reporter: Tomás Dias Almeida
>            Priority: Major
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> Given the case, a PostOperation PO1 implementation is provided for a given 
> operation, but it does not solve a particular need. I would like to be able 
> to create another PostOperation implementation PO2 with a higher ranking and 
> replace the PO1.
> h2. *Current status*
> h3. *Last wins condition*
> [org.apache.sling.servlets.post.impl.SlingPostServlet|https://github.com/apache/sling-org-apache-sling-servlets-post/blob/master/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java]
>  can only store one PostOperation per operation as it is stored like
>  
> {code:java}
> private final Map<String, PostOperation> postOperations = new 
> HashMap<>();{code}
>  
> This map is filled by the binding function per order of activation
>  
> {code:java}
> protected void bindPostOperation(final PostOperation operation, final 
> Map<String, Object> properties) {
>     final String operationName = (String) 
> properties.get(PostOperation.PROP_OPERATION_NAME);
>     if ( operationName != null && operation != null ) {
>         synchronized (this.postOperations) {
>             this.postOperations.put(operationName, operation);
>         }
>     }
> }{code}
>  
> If two classes provide an implementation for the given operation, we run into 
> a concurrency problem and the last activated component "wins" the race and 
> will be used.
> h3. Incorrect map if a component is stopped
> The map is updated using an unbinding method, that relies on the axiom that 
> there is only one PostOperation per operation.
>  
> {code:java}
> protected void unbindPostOperation(final PostOperation operation, final 
> Map<String, Object> properties) {
>     final String operationName = (String) 
> properties.get(PostOperation.PROP_OPERATION_NAME);
>     if ( operationName != null ) {
>         synchronized (this.postOperations) {
>             this.postOperations.remove(operationName);
>         }
>     }
> }
> {code}
> And so, if we have the following scenario: 
>  
>  # PostOperation P1 is activated for operation P
>  # PostOperation P2 is activated for operation P
>  # 
> [SlingPostServlet|https://github.com/apache/sling-org-apache-sling-servlets-post/blob/master/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java]
>  stores P2 as PostOperation for P (as described above)
>  # P2 is stopped for any reason
>  # 
> [SlingPostServlet|https://github.com/apache/sling-org-apache-sling-servlets-post/blob/master/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java]
>  has no PostOperation set for P, but P1 could be the right one.
> h2. Proposal
> Each PostOperation can provide an optional "operation.ranking" integer 
> property.
> bindPostOperation method will store all PostOperations by order of ranking 
> (higher first), PostOperations with no ranking will be added to the end by 
> order of calling.
> unbindPostOperation removes the given PostOperation of the sorted list.
>  
>  
> If you believe that is a good idea, I can provide an implementation to 
> discuss the solution.
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to