I'm starting to learn RabbitMq and use it with my C# code, but it's giving this error:
(Cannot access a disposed object. Object name: 'RabbitMQ.Client.Impl.AutorecoveringModel'.)
I was trying to consume from Rabbit QUEUE and convert to right Task object, but when she goes to ack he gives except and loses the value.
I had this same problem when I was using the 'using' statement to create the rabbitmq connection and channel.
I stopped using it because I needed to keep the channel open for the entire lifetime object.
Note: I created a function to dispose the connection and channel when finished.
Related
I have written a program which requires multiple queues interaction - means consumer of one queue writes message to another queue and same program has consumer to take action on that queue.
Problem: How to handle network time-out issues with queue while sending messages asynchronously using spring rabbit ampq library?or RabbitTemplate.send() function must throw an exception if there are network issues.
Currently, I have implemented RabbitTemplate.send() that returns immediately and working fine. But, If network is down, send function returns immediately, doesn't throw any exception and client code assumes success. As a result, i have in-consistent state in DB that message is successfully processed. Please note that call to send function is wrapped inside transactional block and goal is if queue writing fails, DB commit must also rollback. I am exploring following solutions but no success:
Can we configure rabbitTemplate to throw run-time exception if any network connectivity issue so that client call is notified? Please suggest how to do this.
Shall we use synchronous SendAndReceive function call but it leads to delay in processing? Another problem, observed with this function, my consumer code gets notification while sendAndReceive function is still blocked for writing message to queue. Please advise if we can delay notification to queue unless sendAndReceive function is returned. But call to SendAndReceive() was throwing an amqp exception if network was down which we were able to capture, but it has cost associated related to performance.
My application is multi-threaded, if multiple threads are sending message using sendAndReceive(), how spring-amqp library manages queue communication? Does it internally creates channel per request? If messages are delivered via same channel, it would impact performance a lot for multi-threaded application.
Can some-one share sample code for using SendAndReceive function with best-practices?
Do we have any function in spring-amqp library to check health of RabbitMQ server before submitting send function call? I explored rabbitTemplate.isRunning() but not getting proper result. If any specific configuration required, please suggest.
Any other solution to consider for guaranteed message delivery or handle network time-out issues to throw runtime exceptions to client..
As per Gary comment below, I have set: rabbitTemplate.setChannelTransacted(true); and it makes call sync. Next part of problem is that if I have transaction block on outer block, call to RabbitTemplate.send() returns immediately. I expect transaction block of outer function must wait for inner function to return, otherwise, ii don't get expected result as my DB changes are persisted though we enabled setChannelTransacted to true. I tried various Transaction propagation level but no success. Please advise if I am doing anything wrong and review transactional propagation settings as below
#Transactional
public void notifyQueueAndDB(DBRequest dbRequest) {
logger.info("Updating Request in DB");
dbService.updateRequest(dbRequest));
//Below is call to RabbitMQ library
mqService.sendmessage(dbRequest); //If sendMessage fails because of network outage, I want DB commit also to be rolled-back.
}
MQService defined in another library of project, snippet below.
#Transactional( propagation = Propagation.NESTED)
private void sendMessage(......) {
....
rabbitTemplate.send(this.queueExchange, queueName, amqpMessage);
}catch (Exception exception) {
throw exception
}
Enable transactions so that the send is synchronous.
or
Use Publisher confirms and wait for the confirmation to be received.
Either one will be quite a bit slower.
I have two programs one is a client the other is a server for the client.
The client sends some data to the server like this and then reads the response:
idtcpclient1.WriteLn(command); //Command contains data that the server needs eg. name and surname
progressbar1.StepIt;
sresult := idtcpclient1.ReadLn();
The server then reads the line, manipulates it and creates a SQL Query.
adoquery1.Close;
adoquery1.SQL.Text := 'select * from '+sGrade;
adoquery1.Open;
But as soon as it opens the connection to the database the client gives an error "Connection closed gracefully"
I have tested the server code without the client by simulating the input and it works fine.
I think Indy and AdoQuery are conflicting
If so why and how can I fix it
If not then what is the problem and how should I fix it?
ADO uses apartment-threaded COM objects that have an affinity to the thread that creates them. They cannot be used across thread boundaries unless they are marshalled.
Indy's TCP server is multi-threaded. Each client runs in its own thread.
A thread must call CoInitialize/Ex() to establish its relationship with COM before it can then access any COM objects, and call CoUninitialize() when it is done using COM.
Your server fails because it is raising an uncaught exception that disconnects the client. Most likely because you did not initialize COM.
You need to create ADO objects on a per-client basis, do not use them from the main thread. In the server's OnConnect event, call CoInitialize/Ex(). In the OnDisconnect event, call CoUninitialize(). In the OnExecute event, dynamically create and use new ADO objects as needed.
This does mean that each client will need its own database connection. If you do not want that, then move your ADO logic to a dedicated thread that clients can post requests to when needed. Stay away from doing the database work in the main thread, it does not belong there.
If you use datamodules: you can create one instance of the datamodule per client, to avoid threading errors. Indy can hold a reference to the client's datamodule in the context. Or use a pool of datamodule instances, depending on available resources and traffic.
I have an orchestration that calls a WCF Service, which is a 2-way request/response send port. Like so:
I've been trying to figure out a way to get the orchestration to persist in a state BEFORE the send shape. This is in hopes that when there are exceptions, or the endpoint is down, I can resume the orchestration and have it try to resend to the endpoint.
I've tried wrapping the send/receive shapes in all sorts of scope shapes in order to get it to persist above the send shape, but to no avail. I've read Seroter's blog up and down and tried all the things suggested in his post:
http://seroter.wordpress.com/2007/01/02/orchestration-handling-of-suspended-messages/
For example, if I take down the endpoint and send to it I get a
System.ServiceModel.ServiceActivationException: The requested service, 'https://my-service.svc' could not be activated.
The service instance will remain suspended until administratively resumed or terminated.
If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.
Which is to be expected. As it says, the instance may re-throw the same exception when resumed (which it does no matter what I've tried).
Things I've tried:
Wrapping the Send shape in a atomic scope, but it still get suspended after the exception is thrown.
Wrapping both Send and Receive shapes in atomic scope, but get an error when compiling:
Error 1 an atomic scope may not contain or call a service or scope that contains both the send and the corresponding receive of a requestresponse operation on a 'uses' port or servicelink
Tried wrapping the Send and Receive shapes in a Long-Running scope and catching the exception, then using a suspend shape - but this just results in a dehydrated instance that is waiting for a response from the WCF Service.
I'm not sure of anything else I could try. Basically what I'm asking is, how can I get the orchestration to persist at the "conWrapper" (or anywhere above the sendRCMR...) shape seen in the included image?
For what you're describing, you don't really need to force an Orchestration Persistence.
If the endpoint is down, or the Adapter throws any other error, the Messaging instance will first go into retry mode, then suspend. That's likely the 'instance' the error message you included is referring to.
Once the endpoint is running again, you resume the Messaging instance.
This is the most common scenario.
Have a variable defaulted to false.
Put a long running scope around the send/receive shapes and a expression shape that set the variable to true after the send, have catch blocks for all exceptions (usually one for SOAP, one for System.Exception and a General) to send out an alert and then have a suspend shape after the alert is sent.
Around the scope put a looping shape, while false, loop.
This will allow you to resume the Orchestration until it succeeds in sending.
Do you know if it's possible actually to disconnect a rtmpconnection and how ?
There is no "disconnect" method in the official doc, and also in the rtmpconnection.lzx . So if you know a way out to disconnect the rtmp connection,please let me know. Thanks in advance.
The <rtmpconnection> class in OpenLaszlo uses the ActionScript 3 NetConnection class to connect to the server. The NetConnection class has a method close(), here is the documentation for that:
Closes the connection that was opened locally or to the server and
dispatches a netStatus event with a code property of
NetConnection.Connect.Closed.
This method disconnects all NetStream objects running over the
connection. Any queued data that has not been sent is discarded. (To
terminate local or server streams without closing the connection, use
NetStream.close().) If you close the connection and then want to
create a new one, you must create a new NetConnection object and call
the connect() method again.
The close() method also disconnects all remote shared objects running
over this connection. However, you don't need to recreate the shared
object to reconnect. Instead, you can just call SharedObject.connect()
to reestablish the connection to the shared object. Also, any data in
the shared object that was queued when you issued
NetConnection.close() is sent after you reestablish a connection to
the shared object.
With Flash Media Server, the best development practice is to call
close() when the client no longer needs the connection to the server.
Calling close() is the fastest way to clean up unused connections. You
can configure the server to close idle connections automatically as a
back-up measure.
In the LZX source code for the <rtmpconnection> I can see that NetConnection.close() is only called in case of a connection failure:
<!--- Handle connection failure, attempt to reconnect using altsrc
#keywords private -->
<method name="_handleConnectionFailure" args="msg"><![CDATA[
this._nc.close();
if (this.debug) {
if ($debug) Debug.warn("error connecting to", this._connecturl, ":", msg);
}
....
I don't know why there is no close method defined on the <rtmpconnection> class, but you could add that code for your yourself, by extending the <rtmpconnection> and adding a close method. Just make sure you handle the state variables correctly.
As I haven't used Red5 in a long time, I cannot tell you if Red5 automatically closes NetConnections which are idle.
Maybe I'm missing something basic here, so please correct me if I am. I have a local service and a WinForms app that communicate via WCF, but I seem to end up with a lot of copies of this code in my application:
Public Shared Sub MyLocalMethod1()
Dim tcpBinding As New NetTcpBinding
tcpBinding.SendTimeout = New TimeSpan(0, 0, 5)
Dim tcpFactory As ChannelFactory(Of MyWCFClass.MyWCFInterface) = New _
ChannelFactory(Of MyWCFClass.MyWCFInterface)(tcpBinding, "net.tcp://localhost:4079")
Dim ServiceWCFConnection As MyWCFClass.MyWCFInterface = tcpFactory.CreateChannel
ServiceWCFConnection.MyWCFMethod1()
tcpFactory.Close()
End Sub
I should probably be doing this in some kind of a helper class that creates the connection, lets my service use it, and then closes the connection, so I don't have multiple copies of this connection code. However, should I be leaving this connection open, or does it make sense to close it every time? The WinForm generally calls the service every few seconds, so it may make more sense to try and have a common copy that all these different calls can each access, instead of opening a closing a new connection each time.
It depends on your needs because both approaches are correct. You can wrap your channel creation code into some helper. You will have same functionality as you use at the moment with single place to edit your channel creation code (DRY principle). Usage of the service is slower because each call will create new TCP connection. Use some disposable helper class to represent your created connection.
If you decide to use single channel (proxy) for whole application you have to think about some new complexity. You are using Net.Tcp binding which creates transport session - TCP connection will live for long time. Moreover WCF service instance will live for the same time as the connection because default instancing mode is PerSession. So single service instance will handle all requests from your client = your service will became stateful. Also when you use opened channel for several calls you have to test state of the channel - network problem, server problem, timeout or unhandled exception will switch channel to Faulted state - such channel and related service instance cannot be used any more. You have to abort such channel and open new one.