Using JavaMail from a webapp in GlassFish - glassfish

I have set up a JavaMail session in a backing bean for my JSF application, and it turns out to be fairly easy to send e-mail. However depending on network conditions, it can take a fair amount of time. The Transport.send() method will block the calling thread until the e-mail is sent or the protocol fails somehow.
My question is: Is this okay to do in a JSF backing bean, considering the possibility of many users accessing the server at the same time?
I can create an application-scoped worker thread that would work off of a BlockingQueue to handle all the e-mail in background. Is this the right thing to do?

A posibility is to have an ejb producing jms-messages, an mdb that consumes the messages asyncronously and invokes the Transport.send()
look at this example: http://faeddalberto.blogspot.com/2011/03/sending-email-with-ejb-3-mdb-message.html

Yes, it's better to move anything that uses the network (and thus may be delayed unpredictably) into a separate thread.

Related

How to deal with application crashes with RabbitMQ

Recently, I have implemented RabbitMQ for a couple of use cases. Sending mails is one of them (which is quite common in practice)
My Problem Statement:
A web service(say service A) needs to publish 1000 messages in the queue (which will be picked by some mail sending engine). But unfortunately, after publishing 500 messages to the queue, my app crashes.
Now, if I hit the same service again then the 500 messages that were already pushed in the first go will be pushed again. Though the mails duplication isn't a big deal for now, but is definitely not desired. How to deal with this one. Any thoughts ?
Solutions that I came up with:
Using the batch feature - but it is not supported by AsyncRabbitTemplate so I'm restrained from using that.
Using the database. But that's definitely cumbersome. I won't use this one as well.
If you can identify the duplicates, you can use the Idempotent Receiver enterprise integration pattern on the consumer side.
Spring Integration has an implementation.
However, it's not clear why you are using the async template since that is for send and receive operations. This application sounds like it only needs to send the requests, not wait for a reply.
It's also not clear how batching can help since the crash could occur on the consumer side after it has processed half of the batch.
In either case, you need to track where you got to before the crash.

Akka.Net custom Mailbox, custom IMessageQueue, or something else

We are using Akka.Net and in some cases we need actors to communicate reliably while preserving order over a message queue (i.e. Oracle Advanced Queues or WebSphere MQ, but any message queuing system would work such as RabbitMQ).
We have various requirements why we are using the message queue, so the question isn't if we should be using this with Akka, the question is how.
How would we go about connecting the queue up to Akka so that it is as seamless as possible?
Is a a custom Mailbox the route to go down? Do we need to right a custom IMessageQueue implementation? Or maybe we need a custom router? Are there any specific tests we can run to be sure our Mailbox/IMessageQueue works well with Akka.Net?
EDIT:
Should we maybe looking to implement a custom Transport?
Can any pointers be offered on where to start?
In general implementing custom mailbox based on some reliable queue is not feasible solution - actually it has been already done on the Akka JVM side, and it failed all hopes.
One of the basic reasons is usually the misunderstanding of the basic idea - when people are talking about reliable delivery (that MQ-systems offers), what they really mean, is reliable processing. What if your messages has been send with 100% delivery ratio, but ultimately receiving actor/node has crashed while processing them? From the mailbox point of view everything went smooth...
For this reason, usually the way to go is a dedicated actor - or hierarchy of them - working as a gateway to external messaging system. This way you can not only send message them but also mark them as receive after explicit acknowledgement from successfully completed process. One of the examples may be akka-rabbitmq (written in Scala).

How can I share an object between a Rails instance and a Sidekiq instance

I have a listener (using the Listen gem) object that I'm adding to a constant within an initializer:
LISTENER = Listen.to(REPORT, ERROR, SENT) do |modified, added, removed|
listener.ignore! /\.swp/
listener.ignore /\.DS_Store/
Communicator.notify(added)
end
I put a little admin interface around this functionality, and I display the status of the listener in the view.
In my deployment, I have a Utility instance where all my background jobs run. I may have 1 or many app servers spinning at one time, so I only want this listener to listen on the Utility instance. Sidekiq is my background processor. Therefore, in my admin interface I enlist a simple Sidekiq worker to spin up this listener.
When I obtain the status of the listener, it says it isn't running. But the process is there. This of course is because the App server is attempting to get the listener status from the constant on the application server!
How can I get the status of the object on the Sidekiq server?
Rails 4.2 has implemented GlobalID and here is a good blog post outlining ActiveJob and it covers using GlobalID. (You can parse live object! OMG section)
I know this is an old post but I just came across it and thought this answer might help someone.
Sidekiq and Application Servers do no share memory. Even the Application server instances do not share memory. You will have to use database to share the information between sidekiq and your application.
Add the status of the listener to the database from your sidekiq process. Read the database value in your application server request.
Seems that you want to use Distributed Ruby: http://www.ruby-doc.org/stdlib-2.1.0/libdoc/drb/rdoc/DRb.html.
dRuby allows methods to be called in one Ruby process upon a Ruby object located in another Ruby process, even on another machine. References to objects can be passed between processes. Method arguments and return values are dumped and loaded in marshalled format. All of this is done transparently to both the caller of the remote method and the object that it is called upon.

"The session was closed before message transfer was complete" with WCF reliable sessions

I've got a WCF service that uses reliable sessions. In my tests, I tend to open a channel, call a method and then close the channel.
I often get a The session was closed before message transfer was complete. exception during Close().
Given that my method is synchronous, the message transfer should be complete. If it's reliable sessions causing this problem (because it's still doing something under the hood), surely it's responsible for either blocking my Close() call, or for giving up without throwing an exception?
How do I avoid this exception?
You should find what caused the connection close. Add diagnostics to you server and client config files by using the WCF Service Configuration Editor.
Repro the error and open your logs in the viewer. You will probably find that the message was to large at the serverside.
I had the same problem, the solution was to change operation contract in my interface definition by marking called method as IsOneWay=false which is default setting.
Make sure you haven't change your operation contract for your method to
[OperationContract(IsOneWay=true)]
What you may want to consider is specifying a timeout value in your call to Close() to allow more time for graceful closing. This can spare you many problems. (Although I agree that finding the cause and trying to prevent it is also important).

Concurrent WCF calls via shared channel

I have a web tier that forwards calls onto an application tier. The web tier uses a shared, cached channel to do so. The application tier services in question are stateless and have concurrency enabled.
But they are not being called concurrently.
If I alter the web tier to create a new channel on every call, then I do get concurrent calls onto the application tier. But I want to avoid that cost since it is functionally unnecessary for my scenario. I have no session state, and nor do I need to re-authenticate the caller each time. I understand that the creation of the channel factory is far more expensive than than the creation of the channels, but it is still a cost I'd like to avoid if possible.
I found this article on MSDN that states:
While channels and clients created by
the channels are thread-safe, they
might not support writing more than
one message to the wire concurrently.
If you are sending large messages,
particularly if streaming, the send
operation might block waiting for
another send to complete.
Firstly, I'm not sending large messages (just a lot of small ones since I'm doing load testing) but am still seeing the blocking behavior. Secondly, this is rather open-ended and unhelpful documentation. It says they "might not" support writing more than one message but doesn't explain the scenarios under which they would support concurrent messages.
Can anyone shed some light on this?
Addendum: I am also considering creating a pool of channels that the web server uses to fulfill requests. But again, I see no reason why my existing approach should block and I'd rather avoid the complexity if possible.
After much ado, this all came down to the fact that I wasn't calling Open explicitly on the channel before using it. Apparently an implicit Open can preclude concurrency in some scenarios.
You can cache the WCF proxy, but still create a channel for each service call - this will ensure concurrency, is not very expensive in comparison to creating a channel from scratch, and re-authentication for each call will not be necessary. This is explained on Wenlong Dong's blog - "Performance Improvement for WCF Client Proxy Creation in .NET 3.5 and Best Practices" (a much better source of WCF information and guidance than MSDN).
Just for completeness: Here is a blog entry explaining the observed behavior of request serialization when not opening the channel explicitly:
http://blogs.msdn.com/b/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx