Use AOP with RxJS to make functions Observable

There are no Observable create functions that will observe function invocations on an Object. As a proof of concept I used a JavaScript AOP library, Meld, to accomplish this “function to stream” capability.

Alternatives
This sounds like a job for a mixin, proxy, Object.observe, inheritance, or decorator pattern. There are hundreds of mixin libraries, the new JavaScript Proxy is not readily available, Object.observe was cancelled, etc.
Edit: Via a Dan Abramov tweet (what a busy guy!), I found out about MobX.

Aspect-Oriented Programming (AOP)
AOP is paradigm that allows the separation of cross-cutting concerns via applying “advices” to objects. There are many advice types. The Meld library supports several, for example, ‘before’, ‘around’, ‘on’, ‘after’, ‘afterReturning’, and ‘afterThowing’.

We’ll just use two here: “after” to observe a function invocation, and “around” to observe a property change.

Observe of function
In this example object:

var myObject = {
   myProperty:'15',		

   doSideEffect: function(x){this.myProperty = x;},		

   doSomething: function(a, b) {return a + b;}
};

We want to subscribe to the ‘doSomething’ function in this object. That is, when that function is invoked, the resulting return value should be sent to an Observable stream.

The stream:

 
var subject = new Rx.Subject();
    
var subjectAsObservable = subject.map(function(x){
       console.log("in map x:" + x);
       return x;
});
    
var subscription = subjectAsObservable.subscribe(
       function(x){ // onNext
           console.log("Next in subject: " + x.toString());
       }	
);

Now to apply an After advice to that function “joinpoint” we do:

 
var remover = 
  doAfter(myObject, 'doSomething', subject, 
    function(result) {
        console.log("after function .... ");
    }
);

myObject.doSomething(1, 2); 
remover.remove();

The output of running this is:

 
in map x:3
main.js:3
after function .... 

Note that “When adding advice to object methods, meld returns an object with a remove() method that can be used to remove the advice that was just added.”

“doAfter” function is a simple function wrapper of the ‘after‘ Meld function:

 
/**
 * @param anObject the object to advise
 * @param method the method selector
 * @param subject the subject that observes the function
 * @param afterFunction function to invoke after the advised function returns
 * @return object with remove() method
function doAfter(anObject, method, subject, afterFunction){
    return meld.after(anObject, method, function(result){
    	subject.onNext(result);
    	afterFunction(result);
    });
}

Observe of property change
Some AOP libraries support get/set advices on property changes. AspectJ in Java world supports this. Meld does not, but this can be implemented using an Around advice. This type of advice wraps a function call.

With an Around advice we can record a properties’ value before and after a function invocation. If there is a change, we generate a new event for the Observable stream.

 
remover = meld.around(myObject, getMethodNames, function(methodCall){
    var originalValue = myObject.myProperty;
    
    var result = methodCall.proceed();
    if(originalValue != myObject.myProperty){
        subject.onNext("prop changed: " + originalValue + " -> " + myObject.myProperty);
    }
    
    return result;
});

myObject.doSideEffect('25');

remover.remove();

The above uses a utillity function:

/** Utility function to get all functions in object */
function getMethodNames(obj){
   return Object.getOwnPropertyNames(obj)
        .filter(function(name){
	    return typeof obj[name] === 'function';
        });		
}

When any method in object is invoked that changes the property, we get:

in map x:prop changed: 15 -> 25
Next in subject: prop changed: 15 -> 25

Of course, there is a performance cost to this approach of monitoring property changes. This costs has not been quantified or explored.

Summary
Using AOP an object’s functions can be made into observers. An “after” advice can signal a result event, and using an “around” advice, it is possible to generate events on an Object’s properties. Useful? Unknown. Already possible in ReactiveX ecosystem, not sure.

Possible operators for the above could be:
fromFunction(object, methodSelector)
fromProperty(object, propertySelector)
fromProperty(object, methodSelector, propertySelector).

TODO
Look at the Rx.Observable.fromCallback(func, [context], [selector]) operator. Could it be used to go from function to Observable stream without using AOP, as presented here?

Software used
RxJS: version 4.0.7, rx.all.compat.js
Cujojs Meld: version 1.3.1,

Links

RxJS process loop with toggled operations and canceling

How to create a stream on a button that toggles between two operations, and another button that can cancel the same stream? Observable operators are numerous and very complex, so coming up with a solution, or composing a stream, to any problem can be very difficult. At least, that is what I found while learning all this reactive stuff.

Use case
UI:
Two buttons: one labeled “Start”, and another labeled “Exit”.

Behavior:
First click on ‘Start’ button, changes its label to “Toggle” and starts the operational loop that invokes operation1.

Further click on button, now labeled “Toggle”, will change the operation invoked alternatively to operation2 or operation1.

A click on the ‘Exit’ button will stop the loop stream.

Here is the RxJS based solution running in JS Bin playground: (Ability to re-run is not implemented. ‘Exit’ means you closed the app.)
RxJS toggable and cancellable process loop on jsbin.com

Sure, this would have been much easier with just regular JavaScript. Just create a timer and a listener on each button, etc. Observable streams don’t really add any value for this simple scenario. But, this is just a learning exercise.

Then again, using streams may offer more opportunities for handling more complex scenarios with timer loops.

Similar
This appears to be just like the very basic traditional state machine exercise of modeling a stopwatch. There, the toggle button starts/stops the timer, and the Exit is the cancel button. Do a web image search for “statechart stopwatch”.

Jump to source code

Solution
This seems easy now, but it took a lot to come up with a solution. The approach selected, using ‘scan’ was suggested in an article and a StackOverflow question. ‘Scan’ can be used to transfer statefulness.

For the loop we can create streams using timer or interval.

The alternation of operation is where the complexity comes in. “case” operator is very powerful since it can choose an Observable based on a key into a sources map. Would be useful if the operations, i.e., functions invoked in the loop, are themselves streams or Subjects.

If there is only one operation to execute in the loop and the toggle button is behaviorally a run/pause, then there is the “pausable” operator.

One thing I did not implement is a way to restart the process after it was exited. Do the whole thing as a programmatic setup on first start click, or figure out how to resubscribe to the observables? Oh well.

Software used
RxJS: version 4.0.7, rx.all.compat.js
JQuery 2.2.0: jquery-2.2.0.js

Links


Source
Two versions shown below, ES6 using arrow function expressions, and one using plain functions. I’m sure this is a naive newbie solution to this, so be very skeptical of the RxJS usage here. Note: I named the streams with a “$” prefix. a kind of reverse Hungarian Notation. This is a naming convention used by the Cycle.js project.

Reflective light channels as buriable Solar Cell energy generators.

One of the causes in low efficiency capturing solar radiation via solar cells is the reflection loss. A lot of research on this has resulted in many approaches such as nano-structures to reduce this reflection. An alternative is to embrace reflection. How?

The sun shines on a collector opening and this light is reflected down into a ‘pipe’ or channel. The angle of the reflectors cause the light to bounce from one side to another. Now instead of mirrors being used as reflectors, we use solar cells. Thus, instead of larger solar farms we would have wider and deeper light capture networks. Since the reflection occurs within the channel, this structure can be buried in the ground.

Unknown at this point are the parameters of this pipe or channel? Is this really feasible as large structures or only efficient at nano-scales?

solar cell pipe to reuse reflection
solar cell pipe

© 2016 by Josef Betancourt. All rights reserved

Can conditional state be used in RxJava Observable streams?

Few examples of RxJava contain conditional operations on a stream that involve state transitions based on stream content. Sure there are operators such as filter and the rest, but since examples are “pure”, that is, using pure functions, there is no setting of state that can influence the next event.

It doesn’t seem that this is part of the use-case of reactive streams. At least, that is my current conclusion. I hope it is incorrect. If not then a large type of use-case is not amendable to Reactive approach.

Here is the general problem statement: A stream consists of items x. If the current x has a property p set, then subsequent x will be skipped if they are related to that first x. Note that those skipped x could also have the same property set. This scenario could be generalized to specify an operation on a subgroup besides skipping.

A concrete example of this ‘pattern’ is found at Prune deleted folders of repo diff report using Java. IN that blog post, the x are the output of a Subversion diff report, and the conditional property is folder deletion. We want to prune deleted subfolders.

In Listing 1 below, I solve this with Java 8 streams in method pruneDeletedFoldersJavaStream(List). I also solve it using RxJava in method pruneDeletedFoldersRx(List). However, the Rx approach is just a copy of the Java 8 streams approach, but just using the filter operator. A State object model is used in both since Java 8 requires final fields.

Can this be implemented with the use of Rx operators and no explicit state handling? I tried many approaches, even use of BehaviorSubject, to no avail. I don’t even know how to phrase the question on Stackoverflow.

Listing 1, Full Source

Links

Reactive client application state constraint contracts

As in Design By Contract (DbC), the contents and structure of a Store mutation can be constrained by Preconditions, Postconditions, and Invariants. These constraints are part of the Store implementation.

Background
Modern JavaScript frameworks are now emphasizing a form of “global” state storage. This is not really new, but gained new impetus when React came out, which synergistically combined this with other factors, like components, virtual-DOM, and one-way data flow.

React Stores

“… contain the application state and logic. Their role is somewhat similar to a model in a traditional MVC, but they manage the state of many objects — they do not represent a single record of data like ORM models do. Nor are they the same as Backbone’s collections. More than simply managing a collection of ORM-style objects, stores manage the application state for a particular domain within the application.” — https://facebook.github.io/flux/docs/overview.html

In very large apps and multiple development teams, this Store could become a high maintenance cost and a source of defects.

Non-React Store
For example of a reusable Store implementation see Redux. Amazing video: Dan Abramov – Live React: Hot Reloading with Time Travel at react-europe 2015

Interesting Java implementation of Redux: redux-java.

Maintenance
Today’s great application and shiny new framework are tomorrow’s maintenance nightmare. Thus, it makes sense to add in features that will aid this future support.

Example
A store has a JSON map of { foo : true, fee : false, fum : {…}, … }.

A particular flow in the application will update foo to false. Is that ok?

If foo and fee are in the same ‘context’, can they both be false? Note that the ‘application’ or maintenance developer may not know that there is a relationship between foo and fee. With annotations, dependency injection, and so forth, even perusal of the source could make this determination difficult.

Sure, in a small app and simple Store, it would be easy to trace the program and find out the implicit constraints. In reality, Stores grow complex over time, the app gets complex, new requirements mean many changes, and the developer culprit has left the company. Stores will mutate to resemble the catch-all Windows’ Registry.

To compound this, the control flows are hidden within the framework being used. No matter if its today’s MVC usurper, React, or some Observable liberator, there is spaghetti flow and implicit state somewhere.

“At some point, you no longer understand what happens in your app as you have lost control over the when, why, and how of its state. When a system is opaque and non-deterministic, it’s hard to reproduce bugs or add new features.” —
http://redux.js.org/docs/introduction/Motivation.html

Constraints
One way to reduce issues is to use the techniques from data design and use schema constraints. This does not necessarily mean the use of actual schemas as in XML’s XSD or its wannabe JSON equivalent. One alternative is that the Store has an API for constraint binding to content, new life cycle functions apply the constraints. The result of a constraint violation depends on dev or production deployment, log or throw of exceptions.

Afterword
Notice how in the development world we are going back in time? Central stores, Data flow diagrams, functional programming, FSM (obfuscated), etc. Maybe Object-Oriented Programming was a great distraction like Disco. Time for some real funk. “Maceo, I want you to Blow!

Wow, this synchronicity is weird. I’ve been thinking of this post’s contents for a while. Started to write it and my twitter app on phone rings. @brianloveswords tweets about a blog post by @jlongster: “Starters and Mainainers”. Not exactly the same subject, but was about maintenance.

Links

A Visit from Saint Nicholas: "Twas The Night Before Christmas"

Great poem! Originally called “A Visit from St. Nicholas“. I still remember singing a version of it in a grade school choir.

Doesn’t he sound like the late Mitch Hedberg? The diction and phrasing.

History of Christmas:

When I was in Italy I visited the tomb of the real Saint Nicholas at the Basilica di San Nicola in Bari, Italy.

Merry X-Mas and whatever good and moral stuff you celebrate!

Prune deleted folders of repo diff report using Java

Sometimes the contents of deleted folders are not relevant. Just showing the top level deleted folder or dir is enough. For example, in a branch diff against trunk, folder moves are shown as adds and deletes. But in a diff report, the whole sub node of the deleted folder is output.

In the particular report I was creating everything under the deleted directories was just noise. How to prune that?

BTW, I searched the SVN docs and found no support for this kind of pruning. I also looked at the Git docs to see if it was different, but also found no mention of this use-case.

Example scenario:

d1 (modified)
├ d2 (deleted)
   ┝ d3 (deleted)

If we create a deleted prune report of the above, it would contain, d1 modified, and d1/d2 deleted. It would not contain d1/d2/d3.

The algorithm in psuedocode

Jan 8, 2015: I found a use-case where this algorithm does not work when used with an actual Subversion repository being accessed by SvnKit. Not due to SVNKit of course. Will update when fixed.

 

boolean deleting := false
String deletePath = “”

for each path{
    if deleting then 
            if path starts with deletePath then
                skip path
            else
                deleting = false
                deletePath = “”
                result.add(path)
            endif       
    else
        if path is directory and it is deleted then
            deleting = true
            deletePath = path
        endif
        
        result.add(path)
        
    endif
}

This can be implemented at the script level, for example, using Groovy or some other language.

SvnKit Scenario

In an Subversion Console application I wrote using ReactJS, I used SvnKit at the server side to interface to the Subversion server. Future blog post will discuss this single-page app. One of the React components was a Diff table.

Using the SvnKit library I generated an svn diff summary list. This is a list of SvnDiffStatus objects: List. Among other things, these object contain a path string of the respective resource.

To prune the excess deleted folders I first attempted to create an Object tree structure, then I gave up on that (too slow), finally a co-worker suggested I just sort the paths and do a simple contains comparison. Wow, how did I miss that? I guess I was sidetracked by “Objects” and didn’t use simple scripting techniques.

So to prune the folders we sort and prune the results of an SvnDiffSummary object, svnDiff::
List list = pruneDeletedFolders(sortDiffList(((Receiver)svnDiff.getReceiver()).getEntries()));

Where Receiver is an implementation of ISvnObjectReceiver.

(The SvnDiff entries may already be sorted, but the SvnKit API docs do not specify this).

Sort the diff list using Guava

	private List<SvnDiffStatus> sortDiffList(List<SvnDiffStatus> list) {
		return new Ordering<SvnDiffStatus>() {
			@Override
			public int compare(SvnDiffStatus left, SvnDiffStatus right) {
				return left.getPath().compareTo(right.getPath());
			}
		}.sortedCopy(list);
	}

prune the list

	private List<SvnDiffStatus> pruneDeletedFolders(List<SvnDiffStatus> list){
		String deletedPath = "";
		boolean isDeleting = false;
		
		List<SvnDiffStatus> prunedList = new ArrayList<>();

		for (Iterator<SvnDiffStatus> iterator = list.iterator(); iterator.hasNext();) {
			SvnDiffStatus diff = iterator.next();
			String path = diff.getPath();
			if (isDeleting) {
				if (path.startsWith(deletedPath)) {
					// skip this diff
				} else {
					isDeleting = false;
					deletedPath = "";
					prunedList.add(diff);
				}
			} else {
				if (isDirectory(diff) && isStatusDeleted(diff)) {
					isDeleting = true;
					deletedPath = path;
				}

				prunedList.add(diff);
			}
		}

		return prunedList;

	}

Links

Control multiple PCs with single keyboard and mouse

A software KVM approach is sometimes a good solution. While setting up a new PC I had to access the older PC. I used to use Synergy, but could not find if that software is still around.

Now I’m using ‘Mouse without Borders’. It allows me to control the two PCs, Windows 7 and Windows 10. Works very well. It also shares the keyboard and copy and paste.

Links

Windows 7 Startup Repair can take a very very long time

My PC crashed. This time it boots into Startup Repair screen. For those who haven’t experienced this fun example of high technology, it is a dialog box that says, a check for problems will take a few minutes and a repair could even last an hour. The horror of this dialog is that you don’t know if it is working or just hung. It uses a animated “progress” bar. The blue just goes left to right and repeats.

It kept running so long I just stopped the PC (long power button press). Note, many on web warn about interrupting this repair! I’m so tough, I interrupted it multiple times; it ain’t the boss of me. Anyway, I gave up, let it keep running. I figured the hard drive light is blinking every few seconds and then a few rapid flashes. Maybe it is doing some bit twiddling on the hard drive.

It took approximately 72 hours!!!! At the end I was able to log into Win 7. Of course, the Law of Large Numbers, five minutes later the mailman dropped off a new PC I ordered online.

Ok, I logged in. It’s working. I take back all the trash talk on Windows. But, wait … I said to myself, hmmm, if there were disk errors, I should run a checkdisk and sector scan. So I pick those on the C drive and reboot. Now no screen at all, and the hard drive light is on all the time. Oy veah.

Let me work on the new Windows 10 PC. A cheap box, but the processor is not too shabby An Intel Core i5-6400 CPU @ 2.70Ghz.

HomeGroup can’t connect. There is already an existing old HomeGroup. WTH!

Updates
1. The checkdisk and sector scan finished. System still running. Yes, these two took hours, and worse than a progress idiot box is no UI at all.

2. HomeGroup. Followed some steps given on web. Did not work. I found these instructions that did work: http://answers.microsoft.com/en-us/windows/forum/windows_7-networking/deleting-old-homegroup/66cf9557-9130-4582-9d7b-4f8689699bf7?auth=1.
BurrWalnut writes: “Go to Control Panel > All Control Panel Items > Homegroup > Leave the Homegroup and click Leave the Homegroup. If all the computers leave the Homegroup, it will no longer exist, so it‘s effectively deleted and can be setup again.” Weird.

The same person writes: “A home group with no connected computers is like a god with no worshipers; neither can exist.” That is deep!!!

3. The HP Hardware Diagnostic Tools just ran and I got a failure of the SMART Short Self Test Failed (Error Code HD521-2W). Hard drive failure is imminent.

Progress indicators should also indicate that change is occurring

If an application is showing a progress bar of some kind it means it is doing something. If that something is doing some work not just waiting for a network response, the app should indicator the current work it is doing.

Instead some apps use an “idiot light” approach. Case in point. My PC crashed. Startup Repair is running. All it shows is a progress indicator, not one based on completion status or time left, just a blue rectangle cycling by. Its been running for hours. Is is still doing anything, is it hung, is there hope?

Sure, for many apps, actual work status output is redundant and not useful to the “average” user. So when should more information be shown? When the elapsed time is over some threshold. Or if a user wants more information, they can signal that to the app. Many applications use this approach. Why something so fundamental as repairing disks doesn’t do this is very puzzling.

The same dialog box is used in other parts of Windows 10, like when creating a Restore Point, so we still have the same “idiot light” User Experience Design (UxD).