All posts by jb108

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

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

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!

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

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

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

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

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

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.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

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).

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Sonos unable to add folder due to Kapersky firewall

On laptop I tried to add a local folder on C drive to Sonos. The Sonos controller on the same laptop gave the 1002 error code. This is a timeout?

Tried to find solution on web. Firewall had no issues and anti virus software wasn’t doing anything strange. Just in case, I turned off file scanning. Still have issue. Turned off the Windows firewall; still have problem.

Long story short, Kapersky has a firewall running, doh! Turned that off, Sonos can read local folder. Makes no sense. Why would a firewall block a local app from local folder? Probably because the local Sonos controller has to update the local network with that folder so that other controllers in house can also use it.

Links
Sonos support page on error code 1002

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Windows mouse pointer disappears on second monitor

Started happening recently. Maybe an upgrade or some new glitch in system caused it. Experimenting, and found that turning on the Mouse’s Pointer trails eliminated the problem.

System

  • Windows 7 Professional
  • UltrMon 3.2.2
  • HP PC p6230y
  • AMD Phenon II X4 810 Processor 2.60 GHz
  • System Mouse driver

Related Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Java Properties dupe key detect using subclass

And now for the final word on this ‘problem’, the simplest approach is just to subclass the Properties class. The Properties class extends HashTable and uses it’s put(key,value) method. So we just override that method to do the duplicate key detection.

This was also addressed using Groovy scripting in this post, “Remove duplicate lines using Groovy”.

Source also available as a gist.

package com.octodecillion.util;

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * Detect duplicate properties when loading Properties from stream.
 * <p>
 * 
 * @author jbetancourt
 * @since Nov 18, 2015
 */
public class DuplicatePropertyDetectorWithSubClass {

	/**
	 * Detect duplicate keys in Properties resource.
	 * <p>
	 * @see Properties#load(Reader)
	 * 
	 * @param reader The reader is <b>NOT</b> closed.
	 * @return Map Map where map key is duplicated key and list is values of those keys
	 * @throws IOException reading the stream
	 * @throws Exception 
	 */
	public Map<String, List<String>> load(Reader reader) throws Exception {
		if(reader==null){ throw new NullPointerException("reader cannot be null");}
		final Map<String, List<String>> results = new HashMap<>();
		
		Properties props = new Properties(){
			private static final long serialVersionUID = 1L;

			@Override
			public synchronized Object put(Object key, Object value) {
				if (this.containsKey(key)) {
					List<String> list = new ArrayList<>();
					if (results.containsKey(key)) {
						list = results.get(key);
					} else {
						results.put((String) key, list);
					}

					list.add((String) value);
				}			
				
				return super.put(key, value);
			}
		};
		
		props.load(reader);
		return results;
	}
}

Links
Nice tutorial on Anonymous classes: Anonymous Classes

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Java Properties dupe key detect using CGLIB

In a prior post I used Javassist for Dynamic Proxying of Properties class’s load method. This allowed detection of duplicate keys in a Properties file.

In this post I use the Class Generation Library (CGLIB).

Listing 1, Source available at Gist

package com.octodecillion.util;

import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * Detect duplicate properties when loading Properties from stream.
 * <p>
 * This version uses <a href="https://github.com/cglib/cglib/wiki">CGLIB</a> Dynamic Proxy support.
 * 
 * @author jbetancourt
 * @since Nov 18, 2015
 */
public class DuplicatePropertyDetectorWithCGLIB {

    /**
     * Detect duplicate keys in Properties resource.
     * <p>
     * @see Properties#load(Reader)
     * 
     * @param reader The reader is <b>NOT</b> closed.
     * @return Map Map where map key is duplicated key and list is values of those keys
     * @throws IOException reading the stream
     * @throws RuntimeException for any issue with proxying
     */
    public Map<String, List<String>> load(Reader reader) throws IOException {
        if(reader==null){ throw new NullPointerException("reader cannot be null");}
        
        final Map<String, List<String>> dupeResults = new HashMap<>();
        final String put_method_name = "put";
        
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Properties.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object object, Method method, 
              Object[] args, MethodProxy proxy) throws Throwable {
                if(method.getDeclaringClass() != Object.class && isPut(method.getName())) {
                    System.out.println("Putting: " + args[0]);
                    String key = (String) args[0],value = (String) args[1];
                    if (((Properties) object).containsKey(key)) {
                        List<String> list = new ArrayList<>();
                        if (dupeResults.containsKey(key)) {
                            list = dupeResults.get(key);
                        } else {
                            dupeResults.put(key, list);
                        }

                        list.add(value);
                    }
                }
                
                return proxy.invokeSuper(object, args);
            }
            
            private boolean isPut(String name) {
                return name.equals(put_method_name);
            }
        });
        
        Properties props = (Properties) enhancer.create();
        props.load(reader);

        return dupeResults;
    }
}

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.