[Design of Messaging on JBoss (Messaging/JBoss)] - Re: Remoting - Client Asynchronous Calls
by timfox
"ovidiu.feodorov(a)jboss.com" wrote :
| I don't think that methods that return a non-void result need arguing (with the exception of MessageCallbackHandler.handleMessage(), which I will talk about later). They represent round-trips to the server, and they are invoked because the client needs something from the server. The client cannot continue unless it has the reply it needs, so trying to suggest to replace these with asynchronous calls just for the sake of it seems to me at least questionable
|
| Now let's analyze the methods that don't return anything, but represent life-cycle operations, and rarely used mutators (ConnectionEndpoint's start(), stop(), close(), closing(), setClientID(), SessionEndpoint's addTemporaryDestination(), deleteTemporaryDestination(), unsubscribe(), close(), closing(), ConsumerEndpoint's close() and closing()). How many times a second do you start, stop or close connections? Or how many times a second do you add or delete temporary destinations. These are life cycle methods (we use DEBUG to log them), why would they need to be optimized for speed, when reliability and the convenience of getting the acknowledgment of their successful completion (or not) are much more important? Optimizing these operation do not improve message throughput, which is in the end all that matters.
|
| ConnectionEnpoint.sendTransaction(). When your transaction successfully completes on the server (or, more importantly, when it does not), your client wants to know. Using an RPC style invocation makes propagating exceptions back easy. The alternative would be to asynchronously send the "transaction" and then somehow listen for a confirmation (positive or negative). What would be the benefit of doing that?
|
| SessionEndpoint.send(). See the previous "correct approach" discussion. If you don't invoke this method synchronously, how does the client know that the message has been accepted by the broker?
|
| SessionEndpoint.cancelDeliveries(). This is used to cancel any undelivered messages left in the client buffer when the consumer is closed or to cancel any messages that couldn't be redelivered locally at session recovery. Both cases are extraordinary events that do not impact message throughput performance in any way.
|
| This leaves us SessionEndpoint.acknowledgeBatch(), SessionEnpoint.acknoweldge() and ConsumerEndpoint.more() that can arguably improve the throughput if they're made asynchronous. Also, sending the message to the client for delivery is a good candidate for asynchronicity.
|
| So, getting back to what you said, "In many cases with messaging we don't want RPC (in some cases we do).", I would actually say that in many cases with messaging we want RPC, and is some very special cases we don't.
|
| Remoting should support both modes, and we should choose carefully how we use them.
|
To cut a long story short, of course many operations need to be synchronous, this is not in contention.
However most of the operations (with the exception of send) on the primary execution paths can probably be done asynchronously.
These are the ones that need to be fast, they include:
Sending messages from server=>client
Flow control messages (currently just more()) but we will need to extend this probably.
Acknowledgements (I am pretty sure but not 100% about this one - it needs more thought)
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3979329#3979329
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3979329
19 years, 5 months
[Design of Messaging on JBoss (Messaging/JBoss)] - Re: Remoting - Multiplexed (Bidirectional) Transport
by timfox
"ron_sigal" wrote :
| 2. I'm not sure what a bidirectional channel would look like in Remoting,
|
I was thinking something vaguely similar to the Channel interface in Java NIO, except it would need to support both synchronous and asynchronous invocations.
This could be the lowest level of the layered approach that Scott has suggested, and on top of that the rest of remoting could be layered.
anonymous wrote :
| but there's a sense in which Remoting connections are close to a bidirectional channel. From client to server, there's the option of an invocation which is asynchronous at the application level,
|
Does this mean that in the current implementation the invocation is synchronous at the transport level?
Also, what does the current wire format of the multiplex transport look like? Is it based on frames? Or some other way of doing it?
I'm thinking of how hard/easy it would be to get it to look similar(ish) to the AMQP wire format?
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3979327#3979327
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3979327
19 years, 5 months
[Design of JBossCache] - Re: POJOization of config elements
by manik.surtani@jboss.com
How would implementation-specific values be set? Again, using your BuddyLocator example, I presume this would be using BuddyLocatorConfig.getBuddyLocatorProperties()? We're back to dealing with properties objects; how does this help the MC, except for the case of *known* setters/getters such as getBuddyLocatorClass()?
As an alternative approach (haven't spent *too* many cycles on this):
1) Use a BuddyLocatorConfig that just contains *known* setters/getters, such as BuddyLocatorClass.
2) If people wish to implement their own BuddyLocator, they would also provide their own sublass to BuddyLocatorConfig, adding their own custom setters/getters.
3) The MC would still be able to inject this BLC subclass into the custom BL impl, since the interface methods comply. The BL impl will be responsible for casting the BLC to the BLC subclass and extracting impl-specific configs.
Thoughts?
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3979326#3979326
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3979326
19 years, 5 months
[Design of Messaging on JBoss (Messaging/JBoss)] - Re: Remoting - Client Asynchronous Calls
by timfox
"ovidiu.feodorov(a)jboss.com" wrote :
| Your "correct" approach raises the following issue:
|
| Assume that you want to write a client that needs guaranteed delivery on a queue. You write that client to create a persistent message and send the message by invoking a producer's send() method. As soon as your send() method returns without an exception, this is a hard guarantee to your client that the messaging broker accepted the message for further delivery. You cannot have that guarantee without you call actually reaching the server. At that point, the client can call System.exit() and go to the client's heaven, fully assured that his message is being taken care of. If you use the asynchronous approach you describe, the client will be never able to rely on this guarantee.
|
When I was talking about flow control previously I was specifically talking about pushing messages from server -> consumer, not sending messages from client -> server.
For pushing from server->client, for the reasons already stated (latency problems) an RPC model will ruin performance.
For sending from client to server, yes you are correct in stating this must be RPC, for JMS at least, although AMQP is less strict on this and allows asynchronous send I believe.
(Also bear in mind, that an absence of an exception does imply success, but the presence of an exception does not imply failure - the message could actually have been added to the queue - but this is not particularly relevant to the discussion).
So, for JMS, to maximise sending throughput for a high latency network would be done on the application level by sending messages in transactions with multiple messages per transaction. This allows many messages to be sent in one RPC.
anonymous wrote :
| I disagree with a). An RPC model is very convenient when dealing with life cycle operations such as creating connections, sessions, producer, consumer, browsers, etc. It's a very convenient model for a high granularity reliable operations.
|
Let's be clear on this. I am not advocating an all or nothing asynchronous approach. Of course some operations need to be synchronous.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3979320#3979320
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3979320
19 years, 5 months
[Design of Kosmos] - SvnMonitoringPortlet
by lamerbot
Hello. I'am new to kosmos and when i try to deploy SvnMonitoringPortlet i had next exception:
| [hu.midori.kosmos.server.svn.SvnServiceImpl] Unable to proces
| s the SVN repo org.tmatesoft.svn.core.SVNException: svn: REPORT of '/repos/asf/!svn/bc/465523/d
| b': 400 Bad Request (http://svn.apache.org)
|
| 08:35:38,135 ERROR [hu.midori.kosmos.server.svn.SvnServiceImpl] Unable to proces
| s the SVN repo
| org.tmatesoft.svn.core.SVNException: svn: REPORT of '/!svn/bc/6907/labs/shotoku/
| trunk': 400 Bad Request (http://anonsvn.labs.jboss.com) at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.error(SVNErrorMana
| ger.java:43) at org.tmatesoft.svn.core.internal.io.dav.DAVRepository.log(DAVRepositor
| y.java:487) at org.tmatesoft.svn.core.io.SVNRepository.log(SVNRepository.java:629)
|
Portlet.xml contains next:
| <portlet>
| <portlet-name>JBossSvnMonitoringPortlet</portlet-name>
| <portlet-class>hu.midori.kosmos.portlet.svn.SvnMonitoringPortlet</portlet-class>
| <init-param>
| <name>monitored.resource</name>
| <value>JBoss Labs Subversion</value>
| </init-param>
| <init-param>
| <name>service.url</name>
| <value>http://localhost:8085/kosmos-server/kosmos-services/svn-service</value>
| </init-param>
| <init-param>
| <name>monitored.urls</name>
| <value>
| http://anonsvn.labs.jboss.com/labs/jbossrules/trunk/,
| http://anonsvn.labs.jboss.com/labs/kosmos/trunk/,
| http://anonsvn.labs.jboss.com/labs/shotoku/trunk/,
| http://svn.apache.org/repos/asf/commons/,
| http://svn.apache.org/repos/asf/db/
| </value>
| </init-param>
| <supports>
| <mime-type>text/html</mime-type>
| <portlet-mode>HELP</portlet-mode>
| <portlet-mode>VIEW</portlet-mode>
| </supports>
| <supported-locale>de</supported-locale>
| <supported-locale>en</supported-locale>
| <supported-locale>fr</supported-locale>
| <supported-locale>hu</supported-locale>
| <supported-locale>ja</supported-locale>
| <supported-locale>pl</supported-locale>
| <resource-bundle>hu.midori.kosmos.portlet.svn.svn_monitoring</resource-bundle>
| <portlet-info>
| <title>Subversion Monitoring</title>
| </portlet-info>
| </portlet>
|
I try to start it on liferay and jboss.
Also, uner liferay i catch next exception:
| java.lang.ClassCastException: com.liferay.util.axis.SimpleHTTPSender
| at org.apache.axis.AxisFault.makeFault(AxisFault.java:101)
| at org.apache.axis.client.AxisClient.invoke(AxisClient.java:216)
| at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
| at org.apache.axis.client.Call.invoke(Call.java:2767)
| at org.apache.axis.client.Call.invoke(Call.java:2443)
| at org.apache.axis.client.Call.invoke(Call.java:2366)
| at org.apache.axis.client.Call.invoke(Call.java:1812)
| at _soapclient.JirasoapserviceV2SoapBindingStub.logout(JirasoapserviceV2
| SoapBindingStub.java:3194)
| at hu.midori.kosmos.server.jira.JiraSoapServiceImpl.disconnect(JiraSoapS
| erviceImpl.java:217)
| at hu.midori.kosmos.server.jira.JiraSoapServiceImpl.getProjects(JiraSoap
| ServiceImpl.java:175)
| at sun.reflect.GeneratedMethodAccessor153.invoke(Unknown Source)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
| sorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflecti
| on(AopUtils.java:287)
| at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJo
| inpoint(ReflectiveMethodInvocation.java:181)
| at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
| ReflectiveMethodInvocation.java:148)
| at hu.midori.kosmos.server.MethodResultCacheInterceptor.invoke(MethodRes
| ultCacheInterceptor.java:56)
| at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
| ReflectiveMethodInvocation.java:170)
| at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynami
| cAopProxy.java:176)
| at $Proxy128.getProjects(Unknown Source)
| at sun.reflect.GeneratedMethodAccessor153.invoke(Unknown Source)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
| sorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflecti
| on(AopUtils.java:287)
| at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJo
| inpoint(ReflectiveMethodInvocation.java:181)
| at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
| ReflectiveMethodInvocation.java:148)
| at org.springframework.remoting.support.RemoteInvocationTraceInterceptor
| .invoke(RemoteInvocationTraceInterceptor.java:68)
| at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
| ReflectiveMethodInvocation.java:170)
| at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynami
| cAopProxy.java:176)
| at $Proxy129.getProjects(Unknown Source)
| at sun.reflect.GeneratedMethodAccessor153.invoke(Unknown Source)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
| sorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java
| :157)
| at org.springframework.remoting.caucho.HessianServiceExporter.handleRequ
| est(HessianServiceExporter.java:110)
| at org.springframework.web.servlet.mvc.SimpleHandlerAdapter.handle(Simpl
| eHandlerAdapter.java:46)
| at org.springframework.web.servlet.DispatcherServlet.doDispatch(Dispatch
| erServlet.java:792)
| at org.springframework.web.servlet.DispatcherServlet.doService(Dispatche
| rServlet.java:726)
| at org.springframework.web.servlet.FrameworkServlet.processRequest(Frame
| workServlet.java:396)
| at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServ
| let.java:360)
| at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
| at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
| at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
| icationFilterChain.java:237)
| at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
| ilterChain.java:157)
| at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
| alve.java:214)
| at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
| eContext.java:104)
| at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
| a:520)
| at org.apache.catalina.core.StandardContextValve.invokeInternal(Standard
| ContextValve.java:198)
| at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
| alve.java:152)
| at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
| eContext.java:104)
| at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
| a:520)
| at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
| ava:137)
| at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
| eContext.java:104)
| at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
| ava:118)
| at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
| eContext.java:102)
| at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
| a:520)
| at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
| ve.java:109)
| at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
| eContext.java:104)
| at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
| a:520)
| at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
|
| at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:16
| 0)
| at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
| :799)
| at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
| ssConnection(Http11Protocol.java:705)
| at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java
| :577)
| at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP
| ool.java:683)
| at java.lang.Thread.run(Thread.java:595)
| Caused by: java.lang.ClassCastException: com.liferay.util.axis.SimpleHTTPSender
| at org.apache.axis.deployment.wsdd.WSDDTargetedChain.makeNewInstance(WSD
| DTargetedChain.java:157)
| at org.apache.axis.deployment.wsdd.WSDDDeployableItem.getNewInstance(WSD
| DDeployableItem.java:274)
| at org.apache.axis.deployment.wsdd.WSDDDeployableItem.getInstance(WSDDDe
| ployableItem.java:260)
| at org.apache.axis.deployment.wsdd.WSDDDeployment.getTransport(WSDDDeplo
| yment.java:410)
| at org.apache.axis.configuration.FileProvider.getTransport(FileProvider.
| java:257)
| at org.apache.axis.AxisEngine.getTransport(AxisEngine.java:332)
| at org.apache.axis.client.AxisClient.invoke(AxisClient.java:163)
| ... 64 more
|
What's wrong?
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3979286#3979286
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3979286
19 years, 5 months