Tag Archives: utilities

Add Transform Semantics to Arbitrary Objects!

We can use parametric polymorphism to create containers that add common semantics to different types. Here’s an example of defining “data transform” semantics to objects. The idea is that you lift an object of some type into the transform space. Operations on that transform object keep it in the space of transforms. If at some point the data transform is invalid, subsequent operations will simply pass the invalid transform forward. But it still stays in the transform space.

In the end, you can check the “isValid()” property, and see if your chain of operations was valid. If not, you can get the “invalidReason()” as a String. Otherwise, you can “get()” the final object, which was the result of your operations.

Transform defines the operations allowed on a transform container.

GenericTransform defines a basic container that can hold an arbitrary type

EmptyTransform is the starting point for specific transform types, because it defines a transform on nothing at all, which is always invalid.

StringTransform is the shell of a string transform class specific to String. You can add functions to StringTransform, as long as they return a “Transform” type. That ensures that the methods are chainable, and operations stay in the Transform space.

public interface Transform<A> {

    /**
     * @return true if the object is still valid.
     */
    boolean isValid();

    /**
     * @return the reason we're invalid
     */
    String invalidReason();

    /**
     * Make sure the object is valid before you get it.
     *
     * @return the underlying value.
     */
    A get();

    /**
     * Return true if the data is invalid, and we should stop processing,
     * this returns true. The logic should return an invalid instance as
     * the answer.
     *
     * <p>
     * (Really just sugar for ! isInvalid)
     *
     * <p>
     * Nicer than throwing a hard stop with "halt"
     *
     * @return true if we should skip the following logic
     */
    boolean skipIfInvalid();

    /**
     * If the transformation is to a different underlying type,
     * we can't perform that transformation, so halt -- should
     * involve throwing a RuntimeException.
     *
     * Note that is only a safeguard method; the running code should
     * always check isValid to avoid hitting calls to this method.
     */
    void haltIfInvalid();

    /**
     * Support bind semantics for arbitrary extensibility
     *
     * <p>
     * Note that unit is just the constructor, although we don't
     * support function composition on functions like in Haskell
     *
     * <p>
     * Note that the fist argument to bind (Transform<A> ma) is just this
     */
    <B> Transform<B> bind(Function<A, Transform<B>> f);
}

The Empty transform is the starting point for all others, because it defines operations on a transform with no object.

public abstract class EmptyTransform<A> implements Transform<A> {

    private final boolean valid;

    private final String invalidReason;

    protected EmptyTransform(boolean valid, String invalidReason) {
        this.valid = valid;
        this.invalidReason = (valid) ? "Valid" : invalidReason;
    }

    @Override
    public boolean isValid() {
        return valid;
    }

    @Override
    public String invalidReason() {
        return invalidReason;
    }

    @Override
    public boolean skipIfInvalid() {
        return ! valid;
    }

    @Override
    public void haltIfInvalid() {
        if (! isValid()) {
            throw new InvalidResourceException(invalidReason);
        }
    }

    @Override
    public A get() {
        // normally we'd call haltIfInvalid, but since the EmptyResource
        // is always invalid, fail. Subclasses must override this method
        // or else.
        throw new InvalidResourceException(invalidReason);
    }

    public static <B> Transform<B> invalidBecause(String invalidReason) {
        // In this space, all invalid instances look alike 😉
        return (Transform<B>)new EmptyTransform<B>(false, invalidReason) { };
    }

    @Override
    public <B> Transform<B> bind(Function<A, Transform<B>> f) {
        return EmptyTransform.invalidBecause("Empty transform");
    }
}

The GenericTransform is just a holder for some arbitrary type, but doesn’t define any operations for a specific type.

public class GenericTransform<A> extends EmptyTransform<A> {

    final A o;

    public static <A> GenericTransform<A> invalidBecause(String reason) {
        return new GenericTransform<A>(false, reason);
    }

    public static <A> GenericTransform<A> of(A a) {
        return new GenericTransform<>(a, (a == null) ? Object.class : a.getClass());
    }

    public static <A> GenericTransform<A> of(A a, Class<?>; clazz) {
        return new GenericTransform<>(a, clazz);
    }

    private GenericTransform(boolean valid, String reason) {
        super(false, reason);
        this.o = null;
    }

    @SuppressWarnings("unchecked")
    private GenericTransform(Object o, Class<?> clazz) {
        super(clazz.isInstance(o), "Null or wrongly typed " + clazz.getSimpleName());
        this.o = isValid() ? (A)clazz.cast(o) : null;
    }

    public A get() {
        haltIfInvalid();
        return o;
    }

    public String toString() {
        return Objects.toStringHelper(this)
                .add("valid", isValid())
                .add("invalidReason", invalidReason())
                .add("object", o)
                .toString();
    }

    @Override
    public <B> Transform<B> bind(Function<A, Transform<B>> f) {

        // Guard: stop if we're invalid
        if (skipIfInvalid()) {
            return EmptyTransform.because(invalidReason());
        }

        return f.apply(o);
    }
}

The StringTransform is an example of where you would add operations for a specific type.

public class StringTransform extends EmptyTransform<String> {

    private static final String NO_STRING = "";

    private final String string;

    public static StringTransform invalidBecause(String reason) {
        return new StringTransform(false, reason);
    }

    private StringTransform(boolean valid, String reason) {
        super(false, reason);
        this.string = null;
    }

    public StringTransform(Object string) {
        super(string != null, "String is null");
        this.string = isValid() ? string.toString() : NO_STRING;
    }

    public String get() {
        haltIfInvalid();
        return string;
    }

    @Override
    public <B> Transform<B> bind(Function<String, Transform<B>> f) {

        // Guard: stop if we're invalid
        if (skipIfInvalid()) {
            return anyInvalid();
        }

        return f.apply(string);
    }
}

Leave a comment

Filed under Uncategorized

Python Lockfile using With

I needed lockfile functionality and wanted to use the Python with statement. It creates a lockfile, or else blows away an existing lockfile that’s been there too long.

import os, sys
import fcntl
import errno
import time
from contextlib import contextmanager


@contextmanager
def file_lock(lock_file, timeout=15 * 60):

    # assume no
    fp = None

    try:
        # create the file or fail
        fp = _create(lock_file)
        yield True
    except OSError as e:
        if e.errno != errno.EEXIST:
            raise

        # TODO: check the modified time to see if we should go anyway
        try:
            fp = _refresh(lock_file, timeout)
        except:
            fp = None

        if fp:
            yield True
        else:
            yield False

    finally:
        # clean up after
        if fp:
            _cleanup(fp, lock_file)


def _create(lock_file):
    """Create the file or fail."""
    fp = os.open(lock_file, os.O_CREAT | os.O_EXCL | os.O_RDWR)
    return fp


def _refresh(lock_file, timeout):
    """too old, just overwrite it to update the modified time"""
    fp = os.open(lock_file, os.O_RDWR)
    mtime = time.time() - os.fstat(fp).st_mtime
    if mtime < timeout:
        fp = None
    else:
        fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
        os.write(fp, 'ok')
    return fp


def _cleanup(fp, lock_file):
    """unlock and delete the file"""
    os.close(fp)
    os.unlink(lock_file)

if __name__ == '__main__':
    pass

    with file_lock('zoom.lock') as got_it:
        if got_it:
            print 'Got it!'
            time.sleep(10)
        else:
            print 'EPIC FAIL'

        print 'done'

Leave a comment

Filed under python, utility