Are there any benefits of using wisper gem over rails-observers?
They both looks quite similar at first sight, but wisper seems to be more supported by community (based on GH stars, commits and releases). Are there any significant differences between them?
Rails observers suffer the same problems as ActiveRecord callbacks, primarily that they can't be turned off. With ActiveRecord callbacks you forever couple the model to whatever is referenced in the callback and whatever side effect occurs in the callback always happens in all circumstances. Using observers only really moves the problem.
What if we want to use our model in a context, which we don't foresee today, in which we don't want the observer callback to occur?
If you search StackOverflow for “Rails callbacks”, a large number of
the results pertain to seeking means to avoid issuing the callback in
certain contexts. It almost seems as though Rails developers discover
a need to avoid callbacks as soon as they discover their existence.
ref: http://samuelmullen.com/2013/05/the-problem-with-rails-callbacks/
Wisper (disclaimer, author here) allows publishers (e.g. a model) to broadcast events when something significant happens. Listeners are subscribed to the publishers, at runtime. The publishers and subscribers know nothing of each other. Instead of having a hard dependency on each other, they only depend on the event.
Our systems, by necessity, have dependencies between objects, they need to communicate. However we want this dependency to be as light as possible so that an object can be used, in the future, in different contexts we currently might not be able to foresee today. Also see Connascence for examples of light/hard dependencies.
Using Wisper, in different contexts you can choose to subscribe a listener or not.
For example in a controller I might subscribe some listeners, but in my unit test I might want to test the model isolation, without these side effect occurring. Another example might be a rake task, where I want to save a model but do not want certain side effects to occur. Or an admin controller where I do/don't want something to which should/shouldn't happen in other contexts.
Finally Wisper has built-in support for asynchronous broadcasting of events which Observers do not, they are always synchronous.
Related
I have a system, connected to financial markets, that makes a very heavy use of events.
All the code is structured as a cascade of events with filters, aggregations, etc in between.
Originally the system was written in C# and then ported to F# (which in retrospect was a great move) and events in the C# code got replaced by events in F# without giving it much thoughts.
I have heard about the observer pattern, but I haven't really gone through the topic. And recently, I have read, through some random browsing, about F#'s Mailbox processor.
I read this: Difference between Observer Pattern and Event-Driven Approach and I didn't get it, but apparently over 150 people voted that the answer wasn't too clear as well :)
In an article like this: https://hackernoon.com/observer-vs-pub-sub-pattern-50d3b27f838c it seems like the observer pattern is strictly identical to events...
At first glance, they seem to be solving the same kind of problems, just with different interfaces but that got me to think about 2 questions:
Is the mailbox processor really a thing being used? it seems to appear mostly in older documentation and, in the packages I'm using, I haven't come across any using it
Regarding the observer pattern, only one package across the sizeable amount we're using makes internal use of it, but everything else is just using basic events.
Are there specific use cases fitting the Observable pattern and the MailboxProcessor? Do they have features that are unique? or are they just syntactic help around events in the end?
As simplified as possible:
Mailbox
This is a minimal implementation of the actor model.
You post messages to a queue, and your loop reads the messages from the queue, one by one. Maybe it posts to another mailbox or it does something with the messages.
Any action can only take place when a message is received.
Posting to the queue is non-blocking, i.e, no back-pressure.
All exceptions are caught and exposed as an event on the mailbox. They are expected to be handled by the actor above it.
Other actor frameworks provide features like supervisors, contracts, failover, etc.
Events
Events are a language supported callback mechanism.
It's a simple implementation. You register a callback delegate, and when the event is raised, your delegate is called.
Delegates are called in the order they are added.
Events are blocking, and synchronous. The one delegate blocks, the rest are delayed.
Events are about writing code to respond to events, as opposed what came before it, which was polling.
The handler for an event is usually the final end-point for that event, and it usually has side-effects.
Sharing a handler is common. For example, ten buttons might have the same function handling clicks, because the sender of the event is known.
You handle exceptions by yourself, typically in the handler code
Observables
There's a source (Observable) which you can subscribe to with a sink (Observer). An observable represents a bounded or un-bounded stream of values. An unbounded stream (an Observable which never completes) seems similar to an event, but there are several important properties to Observables.
An Observable emits a series of notifications, which follows this contract:
OnNext* (OnError|OnCompleted)+
All notifications are serialized
Notifications may or may not be synchronous. There's no guarantee of back-pressure.
The value of Observables lies in the fact that they are compose-able.
An observable represents a stream of future notifications, operators act to transform this stream.
This approach is sometimes called complex event processing (CEP).
Exception handling is part of the pipeline, and there are many combinators to deal with it.
You typically never implement an Observer yourself. You use combinators to set up a pipeline which models the behavior you want.
I am trying to build an offline synchronization capability into my iOS App and would like to get some feedback/advice from the community on the strategy and best practice to be followed to do the same. The app details are as follows:
The app shows a digital catalog to users and allows them to perform actions like creating and placing orders, among others.
Currently the app only works when online, and we have APIs for all actions like viewing the catalog, creating/placing orders which return JSON data.
We would like to provide offline/synchronization capability to users, through which users can view the catalog and create/place orders while offline, and when they come online the order details will be synchronized and updated to our server.
We would also like to pull the latest data from the server, and have the app keep itself up to date in case of catalog changes or order changes that happened at the Server while the app was offline.
Can you guys help me to come with the best design and approach for handling this kind of functionality?
I have done something similar just in the beginning of this year. After I read about NSOperationQueue and NSOperation I did a straight forward approach:
Whenever an object is changed/added/... in my local database, I add a new "sync"-operation to the queue and I do not care about, if the app is online or offline (I added a reachability observer which either suspended the queue or takes it back working; of course, I do re-queueing if an error occurs (lost network during sync)). The operation itself reads/writes the database and does the networking stuff. My ViewController use a NSFetchedResultsController (with delegate=self) to get callbacks on changes. In some cases I needed some extra local data (it is about counting objects), where I have used NSManagedObjectContextObjectsDidChangeNotification.
Furthermore, I have used Multi-Context CoreData which sounded quite reasonable to use (I have only two contexts).
To get notified about changes from your server, I believe that iOS 7 has something new for you.
On the server side, you should read a little for the actual approach you want to go for: i.e. Data Synchronization by Dan Grover or Developing Android REST Client Applications (of course there are many more good articles out there).
Caution: you might be disappointed when you expect an easy solution. Your requirement is not unusual, but the solution might become more complex than you expect - depending on the "business rules" and other reasonable requirements. If you intelligently restrict your requirements you may find a solution which you can implement yourself, otherwise you may also consider to use a commercial product.
I could imagine, that if you design the business logic such that it takes an offline state into account and exposes this explicitly in the business logic, you may find a solution which you can implement yourself with moderate effort. What I mean by this is for example, when a user creates an order, it is initially in "not committed" stated. The order will only be committed when there is access to the server and if the server gives the "OK" that this order can actually be placed by this user. The server may also deny the order, sending corresponding messages to the user.
There are probably quite a few subtle issues that may arise due to the requirement of eventual consistency.
See also this question which contains pointers to solutions from commercial products, and if you visit their web sites give valuable information about the complexity of the problem and how this can be solved.
I am using Rails 3.1.0 with Devise 2.1.0. I would like to limit the number of times a user can perform an action in a day. The main purpose of this limitation is to prevent spam.
I see many questions similar to this one but was wondering if there is a specific way to accomplish what I am trying to do through Devise.
For the actions that create model instances, the number of times an action has been performed in a day is easy to keep track of. However, at least one action that I would like to restrict does not create a model instance, so I'm not sure what to do about it.
I was also wondering if this is a legitimate/effective way of preventing spam (in addition to requiring users to register and sign in to perform the actions).
Personally, I find these sorts of systems to be over-complications. Unless spam is an existing, provable problem I'm not sure adding in a system that's likely to be rather extensive is a good use of time and energy.
Alternatives to this would be requiring registration through a third-party service (say Facebook) and using either captchas or exciting and new negative captchas.
That said, if you want to do this, I think the best place to keep track of it would be in an ephemeral data store. Redis would be really good for this since you can use queues. In the actions that you want to restrict, add a timestamp to the queue, and before you allow the user to perform said action, check the number of elements in the queue, purging ones that are too old while you do so.
That's sort of pseudo-codey, but should at least help you get started.
I need to monitor user changes on active record level with associations. This changes should be displayed on a stream like page. Since every user has different permission on different areas of my application also the audit stream has to be limited to their permissions.
I know about Paper trail (does not work on all type of relations:( ), Vestal versions, acts_as_audit and so on, but do not know what is the best practise to use this gems as described in my case.
What is the best practise to audit AR changes including associations and display in an activity stream with different user rights ?
A simple way to audit AR activities is provided by Rails with Observer.
Observer allows to add callback function on Models. You can then update an Acitivty model allowing to see what has been changed. Take note that Observer are independent of Controller. What or Whoever change your model should pass through your observer. The drawback is that it can slow down your application.
A more efficient but also more complicated way would be to use EventMachine. See this article for an introduction about it.
A way between EventMachine and Observer could be to use delayed jobs with Observers. If you have to compute something when auditing, it can allow you to do it without slowing down your application like a sleeping turtle. There's some good tips here about Delayed Jobs.
I worked my way through the Prism guidance and think I got a grasp of most of their communication vehicles.
Commanding is very straightforward, so it is clear that the DelegateCommand will be used just to connect the View with its Model.
It is somewhat less clear, when it comes to cross Module Communication, specifically when to use EventAggregation over Composite Commands.
The practical effect is the same e.g.
You publish an event -> all subscribers receive notice and execute code in response
You execute a composite command -> all registered commands get executed and with it their attached code
Both work along the lines of "fire and forget", that is they don't care about any responses from their subscribers after firing the event/executing the commands.
I have trouble seeing a practical difference in usage although I understand that the implementation of both (under the hood) is very different.
So should we think of what it actually means - Event? Is that when something happens (an event occurs)? Something the user did not directly request like a "web request completed"?
And Command? Does that mean a user clicked something and thus issued a command to our application, requesting a service directly?
Is that it? Or are there other ways to determine when to use one of these communication vehicles over the other. The guidance, although one of the best documentations I read, gives no specific explanation.
So I hope people involved in/using Prism can help in shedding some light on this.
There are two primary differences between these two.
CanExecute for Commands. A Command
can say whether or not it is valid
for execution by calling
Command.RaiseCanExecuteChanged() and
having its CanExecute delegate
return false. If you consider the
case of a "Save All"
CompositeCommand compositing several
"Save" commands, but one of the
commands saying that it can't
execute, the Save All button will
automatically disable (nice!).
EventAggregator is a Messaging
pattern and Commands are a
Commanding pattern. Although
CompositeCommands are not explicitly
a UI pattern, it is implicitly so
(generally they are hooked up to an
input action, like a Button click).
EventAggregator is not this way -
any part of the application
effectively raise an EventAggregator
event: background processes,
ViewModels, etc. It is a
brokered avenue for messaging
across your application with support
for things like filtering,
background thread execution, etc.
Hope this helps explain the differences. It's more difficult to say when to use each, but generally I use the rule of thumb that if it's user interaction that raises the event, use a command for anything else, use EventAggregator.
Hope this helps.
Additionally, there is one more important difference: With the current implementation, an event from the EventAggregator is asynchronous, while the CompositeCommand is synchronous.
If you want to implement something like "notify that event X happened; do something that relies on the event handlers for event X to have executed", you either have to do something like Application.DoEvents() or use CompositeCommands.