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

Alex Rudyy commented on QPID-7658:
----------------------------------

My review comments for commits [ https://svn.apache.org/r1785660 ], [ 
https://svn.apache.org/r1785976 ] and [ https://svn.apache.org/r1786358 ]:

* Methods {{NamedAddressSpace#getSendingLink(String, String)}} and 
{{NamedAddressSpace#getReceivingLink(String, String)}} can be replaced with 
{{NamedAddressSpace#getLink(String remoteContainerId, String linkName, boolean 
isReceiving)}}. That would eliminate the need of if-else block in the 
{{Session_1_0#receiveAttach}} and simplify the code.
* Method {{AMQPSession#doOnIOThreadAsync}} was added to public interface but so 
far it is only required by AMQP 1.0 layer. Is it an intention to have this 
method available for 0.x AMQP implementation?
* LinkImpl
** {{LinkImpl#attach}} precondition check below looks wrong:
{code}
if (_role == attach.getRole())
{
    throw new AmqpErrorException(new Error(AmqpError.ILLEGAL_STATE, "Cannot 
switch SendingLink to ReceivingLink and vice versa"));
}
{code}
Should it actually be {code}if (_role != attach.getRole()){code}?
I am not sure that CSRE is required to throw if link endpoint after creation is 
null
{code}
 _linkEndpoint = createLinkEndpoint(session, attach);
if (_linkEndpoint == null)
{
    throw new ConnectionScopedRuntimeException(String.format(
            "LinkEndpoint creation failed for attach: %s",
            attach));
}
{code}
Would it be better to create an instance of {{ErrantEndpoint}} or a 
{{StandardReceivingEndpoint}} with error when target is null? Although 
ConnectionScopedRuntimeException is turned into ErrantEndpoint in catch block 
and the behaviour seems  like spec complient( As per spec "If no target is 
specified on an incoming link, then there is no target currently attached to 
the link. A link with no target will never permit incoming messages") I would 
avoid throwing CSRE here as it would be reported as INTERNAL ERROR which is 
wrong?
** {{#attach}}: Null check for _linkEndpoint and getting a session is racy as 
_linkEndpoint can be nulified between check and call. I would consider saving  
_linkEndpoint in local variable and using local variable where where it is 
feasible. Alternatively, we can consider using atomic state variable in 
LinkImpl and use compareAndSet where it is possible but that might complicate 
code on stealing...
** {{LinkImpl#stealLink}}: it closes the link endpoint with 'close' flag set to 
true as required by the spec. But the side effect of the linkendpoint close is 
that {{Link_1_0#linkClosed()}} is called which deletes the link from the 
registry and its store. The removal of link from registry does not look 
nesessary to me.
* Class ErrantLinkEndpoint looks a bit artificial. Why we cannot have methods 
{{hasError}} and getError on {{LinkEndpoint}} interface instead?
The code in {{Session_1_0$EndpointCreationCallback#success}}
{code}
if (endpoint instanceof ErrantLinkEndpoint)
{
    endpoint.sendAttach();
    ((ErrantLinkEndpoint) endpoint).closeWithError();
}
else if (attachWasUnsuccessful(endpoint))
{
    endpoint.sendAttach();

    Error error = new Error();
    error.setCondition(AmqpError.NOT_FOUND);
    endpoint.close(error);
}
{code}
could be replaced as below
{code}
if (endpoint.hasError())
{
endpoint.sendAttach();
endpoint.close(enpoint.getError()); // or endpoint.close();
}
{code}
That would simplify the code.
* {{SendingLinkEndpoint}}
** {{SendingLinkEndpoint#_durability}} is unused
** {{SendingLinkEndpoint}} would be better to rename into 
{{AbstractSendingLinkEndpoint}}.
** {{SendingLinkEndpoint#remoteDetachedPerformDetach}} there is a posibillity 
of sending multiple detaches in sequence.
* {{ReceivingLinkEndpoint}}
** {{ReceivingLinkEndpoint#_remoteDrain}} is unused. Is it a duplicate of a 
{{_drain}} field an {{AbstractLinkEndpoint}}?
** {{ReceivingLinkEndpoint#_drainLimit}} is unused. The field is used to 
evaluate result returned from {{ReceivingLinkEndpoint#isDrained}} but it seems 
the only place where it called is {{ReceivingLinkEndpoint#receiveFlow}} 
followed by noop. It is unclear what interntions are behind the {{#isDrained}} 
code and unused fields.
* Session_1_0#receiveAttach: Error message ("inputHandle of Attach already in 
use: " + attach.toString()) can be changed to be the same as in  
ConnectionScopedRuntimeException ("Input Handle '%d' already in use").
* I am wondering whether interfaces Link_1_0 and LinkEndpoint can be made 
parameterised (Link_1_0<S extends BaseSource, T extends BaseTarget> 
LinkEndpoint<S extends BaseSource, T extends BaseTarget>) and concreate 
instances could use there own Source and Target implementations. That should 
eliminate the need for casting.

> [Java Broker] Improve LinkRegistry
> ----------------------------------
>
>                 Key: QPID-7658
>                 URL: https://issues.apache.org/jira/browse/QPID-7658
>             Project: Qpid
>          Issue Type: Task
>          Components: Java Broker
>            Reporter: Lorenz Quack
>             Fix For: qpid-java-broker-7.0.0
>
>
> Currently the AbstractVirtualHost has a Map<remoteContainerId, LinkRegistry>.
> The handling of the remoteContainerId should also be encapsulated in the 
> LinkRegistry giving each VH only a single LinkRegistry.
> The LinkRegistry is responsible for ensuring Link uniqueness and persistence 
> (separate JIRA).
> Furthermore, the following change to the LinkRegistry is proposed:
> * LinkRegistry.getSendvingLink(String remoteContrainerId, String linkName) -> 
> Link
> * LinkRegistry.getReceivingLink(String remoteContrainerId, String linkName) 
> -> Link
> These should always return a non-null Link. The caller (session) is 
> responsible for checking that the link has valid Source and Targets.
> They also need to be thread-safe (e.g., two calls with the same arguments 
> should return the same object).
> The LinkRegistry should also provide facilities to the Link to remove itself 
> from the Registry (for example on Link close, or error) and to update the 
> Termini upon resuming a Link.
> If possible this should not be part of the public API. possible API:
> * LinkRegistry.removeSendingLink(String localContainerId, String 
> remoteContrainerId, String linkName)
> * LinkRegistry.removeReceivingLink(String localContainerId, String 
> remoteContrainerId, String linkName)
> * LinkRegistry.updateLinkTermini(Link link, Source source, Target target)
> The implementation of which must be thread-safe because the LinkRegistry will 
> be accessed on multiple threads concurrently.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to