Friday, 11 December 2015

Suppress ready and complete log messages from rack-timeout

The rack-timout gem has an annoying habit of logging two lines for each request at INFO level, e.g.:
source=rack-timeout id=11b2abd0-d4af-4a13-9c5a-a8729af45e40 wait=15ms timeout=29985ms state=ready
source=rack-timeout id=11b2abd0-d4af-4a13-9c5a-a8729af45e40 wait=15ms timeout=29985ms service=165ms state=completed

I like logging at INFO in production because I get a log message per request.

You can reduce the log level rack-timeout uses to log those states by adding this to your initializer:
Rack::Timeout::StateChangeLoggingObserver::STATE_LOG_LEVEL[:ready] = :debug
Rack::Timeout::StateChangeLoggingObserver::STATE_LOG_LEVEL[:completed] = :debug

Thursday, 24 September 2015

Bootstrap and Equal Height Columns

We have a page with 3 columns: a left sidebar, main content in the middle and a right aside for help content. The columns are re-ordered for small screens using Bootstrap's push/pull classes. The content is dynamic and quite often there's a significant different in height.

We wanted to either shade the columns or put a vertical line in between. At 768px and below no background and the usual stacking.

This turned out to be quite a challenge, but http://webdesign.tutsplus.com/tutorials/quick-tip-solving-the-equal-height-column-conundrum--cms-20403 came to my rescue.

There was a wrinkle caused by the Bootstrap columns having position: relative applied to them.

This may not be the best solution (requires extra markup), but it felt like a reasonable compromise:

<div class="row column-background-wrapper">
  <span class="column-background column-1"></span>
  <div class="col-sm-3">
    ...
  </div>

  <span class="column-background column-2"></span>
  <div class="col-sm-5">
    ...
  </div>

  <span class="column-background column-3"></span>
  <div class="col-sm-4">
    ...
  </div>
</div>

And the CSS:

.column-background-wrapper {
  position: relative;
}

.column-background {
  display: none;
}

@media (min-width: 768px) {
  .column-background {
    bottom: 0;
    display: block;
    position: absolute;
    top: 0;
    z-index: -1;
  }

  .column-1 {
    left: 0;
    background-color: #eee;
    width: 25%;
  }

  .column-2 {
    left: 25%;
    // no background needed
    width: 41.66666667%;
  }

  .column-3 {
    left: 66.66666667%;
    background-color: #eee;
    width: 33.33333333%;
  }

}

The % values in the CSS change according to your column setup. And if you use different column sizes at different screen sizes, you would need to replicate that configuration with your own media queries.

http://www.bootply.com/Toa7I16QEQ

Tuesday, 24 March 2015

Basic Rails App

To create a basic application in Rails with some model validation:

rails new demo
cd demo
rails generate scaffold idea name:string{50} description:text{100}
rake db:migrate
cat > app/models/idea.rb <<EOF
class Idea < ActiveRecord::Base
  validates :name, presence: true, length: { maximum: 50 }
  validates :description, length: { maximum: 100 }
end
EOF
rails s

Friday, 27 February 2015

Heroku, Rails, Postgres and database purge and setup

If you delete Rails migrations after they are used, and then reset your production Heroku Postgres database:

heroku pg:reset DATABASE

All you can do to get your database schema back (error free) is 
heroku run rake db:schema:load. If you then try to heroku run rake db:seed (and you have foreign keys) you will get errors like:

PG::InsufficientPrivilege: ERROR:  permission denied: "RI_ConstraintTrigger_a_12949367" is a system trigger

The solution is to reset your development database and then push that pristine copy to heroku, ie.

# wipe and recreate your development database
bundle exec rake db:purge db:setup
# wipe your production database
heroku pg:reset DATABASE

# push your local development database to Heroku
heroku pg:push yourappname_development HEROKU_POSTGRESQL_PINK_URL --app yourappname

yourappname_development - your local development database name
HEROKU_POSTGRESQL_PINK_URL - your production Heroku database name (heroku pg:info to find out)
yourappname - your Heroku application name



Another case where this error comes up is using fixtures to update "static" data in production database. If you are using Heroku you cannot just become the Postgres super-user and disable the constraint.

But this works (from a psql prompt, eg. heroko pg:psql) ...

# verify the foreign key constraint on the table and it's name:
\d table_name
# drop the foreign key constraint
alter table table_name drop constraint fk_rails_01234abcde;
#
# now run your fixtures and/or whatever re-seeding you need to do
#
# create the dropped foreign key
alter table table_name add constraint fk_rails_01234abcde foreign key(column_name) references other_table(id);

Friday, 30 January 2015

Integrate a Bootswatch theme into a Rails 4 app by hand

Adding yet another Gem into my application just to incorporate a Bootstrap theme (from Bootswatch)  seemed like overkill. Doing it manually was not hard…

Following the instructions for the bootstrap-sass Gem, we start with an app/assets/stylesheets/application.css.scss that looks like:

  @import "bootstrap-sprockets";
  @import "bootstrap";

Say we want to use the Yeti theme, download the _bootswatch.scss and _variables.scss files from the Bootswatch site. Place the files in a vendor/assets/stylesheets/bootswatch/yeti/ directory in your Rails project. 

Finally add the new @import statements in your app/assets/stylesheets/application.css.scss file, leaving it looking like:

  @import "bootswatch/yeti/_variables";
  @import "bootstrap-sprockets";
  @import "bootstrap";
  @import "bootswatch/yeti/_bootswatch";

The order of the imports is important. I have a comment block above those imports that reads:

  // order is important here
  // 1. theme variable overrides
  // 2. theme variables
  // 3. any core bootstrap variable overrides
  // 4. bootstrap-sockets and bootstrap
  // 5. theme styles
  // 6. application styles

Thursday, 22 January 2015

Linuxmint Dropbox icon ugly background

Linuxmint 17.1 "Rebecca"
NVidia proprietary driver (331.113)

After installing the NVidia drivers, the Dropbox icon in the system tray has (in my case) a solid black background rather than the colour of the panel.

Found the fix at http://crunchbang.org/forums/viewtopic.php?pid=414074#p414074

cd ~/.dropbox-dist/dropbox-lnx.x86_64-3.0.5
cp -p libGL.so.1 libGL.so.1.orig
ln -sf /usr/lib/nvidia-331/libGL.so.1

After that stop and start Dropbox and the icon background colour is normal

Tuesday, 14 August 2012

Mac OSX NoSleep

Little bit of Free Software to give you some control over what happens when you close your MaxBook's lid.

http://code.google.com/p/macosx-nosleep-extension/

Tuesday, 3 April 2012

Thuderbird SMTP error '5.5.4 Invalid Address' connecting to Exchange server

Using Thunderbird to connect to the Exchange server, I was getting the error:  5.5.4 Invalid Address. Turns out it's something to do with Exchange not liking the EHLO parameter generated by Thunderbird. You can override this value with the following entry in your prefs.js file (change 'smtp1' to whichever is the smtp server you need to fix):

user_pref("mail.smtpserver.smtp1.hello_argument", "your_hostname")

Monday, 27 February 2012

Cygwin cron no password

When you set Cygwin's cron up to run per-user with no password (using cyglsa), then whenever you change your Windows password, you need to:
  1. run Cygwin as the Windows Administrator (right click -> Run as administrator)
  2. run: password -R

Bitlocker in bootcamp Windows 7 on a MacBook Air (late 2010)

The MacBook Air (well at least the 11", late 2010 model) does not have a "TPM" chip, and you'll get an error if you try an enable Bitlocker on the drive. There is a work-around to disable the TPM requirement, though you will need to have a USB key handy every time you boot.


To disable the TPM requirement:
  1. Start the Group Policy Editor
  2. Go to Computer Configuration, Administrative Templates, Windows Components, BitLocker Drive Encryption, and Operating System Drives
  3. Edit the Require additional authentification at startup option
  4. Select the Enable option
  5. Run gpupdate.exe /force
Now you can enable Bitlocker.

UNFORTUNATELY, you then hit a snag with rEFIt not allowing you to boot off the USB key after Windows is installed, and the Bitlocker process requiring you to boot from the USB key to decrypt the drive. So, this process is pointless until rEFIt fixes that bug.

Sunday, 13 November 2011

Boot Camp Windows 7 (64-bit) on a Macbook Air (late 2010)

Installing Windows 7 (64-bit) on a Macbook Air (late 2010 model) via Boot Camp running Snow Leopard (10.6), I ran into porblems with the trackpad driver blue screening. Taking care with the installation process, I was able to avoid the problems.

Updating Boot Camp before Windows after the initial installation is complete is the key:
  1. Setup the partition using Boot Camp. I also use rEFIt to (a) allow installation from a USB drive, and (b) allow me to run Windows 8 in the last partition. You are only allowed 4 primary partitions, but there is a method to install Windows 7 without the extra 100MB partition it wants to create.
  2. Boot from the USB drive without any network connectivity and install Windows 7 as you normally would. If you have a network cable attached, after the installation is complete, you'll be in a race with the Windows 7 updater to install the Boot Camp update first. If you're using wifi, it's easy, just don't put your password in until Boot Camp is all up-to-date.
  3. Install the original Boot Camp WindowsSupport program, and reboot as requested.
  4. Check Windows 7 automatic updating is set to "manual", and enable your network connection.
  5. Run the Apple Software Update program and install the Boot Camp 3.2 update, and reboot as requested.
  6. Run the Apple Software Update program and install the Boot Camp 3.3 update, and reboot as requested.
  7. Install the Windows 7 SP1.
  8. Install the Windows 7 updates from Microsoft.
The same process worked for me in the Windows 8 Developer Preview installation.

Friday, 9 September 2011

Maven and Oracle's JDBC driver

Due to licensing restrictions, the Oracle JDBC driver jar will not be in the repository. The 
pom is there, and it's useful to add that to the conguration:

<dependency>
	<groupId>com.oracle</groupId>
	<artifactId>ojdbc14</artifactId>
	<version>10.2.0.4.0</version>
</dependency>

After that is done, you will then see an error message from mvn about "Could not find artifact com.oracle:ojdbc14:jar:10.2.0.4.0 ...". To resolve that, you need to manually add the JDBC driver jar file to your local .m2 repostiory:

mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 \
-Dversion=10.2.0.4.0 -Dpackaging=jar -Dfile=/path/to/ojdbc14.jar


PS: The ojdbc14.jar file will be on your database server in the ${ORACLE_HOME}/jdbc/lib/ directory.

Maven and Hibernate and Unit Tests (example using the JDK logger)

While attempting to run some unit tests that rely on the H2 in-memory database, I saw this failure:
...
Caused by: java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
	at org.slf4j.LoggerFactory.getSingleton(LoggerFactory.java:223)
	at org.slf4j.LoggerFactory.bind(LoggerFactory.java:120)
	at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:111)
	at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:269)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:242)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:255)
	at org.hibernate.cfg.Configuration.(Configuration.java:165)
	[snip]
	... 74 more
Caused by: java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	... 82 more

The maven dependency:tree target shows:
[INFO] +- org.hibernate:hibernate-core:jar:3.5.0-Final:compile
[INFO] |  +- antlr:antlr:jar:2.7.6:compile
[INFO] |  +- dom4j:dom4j:jar:1.6.1:compile
[INFO] |  |  \- xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] |  +- javax.transaction:jta:jar:1.1:compile
[INFO] |  \- org.slf4j:slf4j-api:jar:1.5.8:compile

The org.slf4j:slf4j-api.jar provides the interface, but not a logging implementation. To add the JDK logger implementation, and additional dependency is required:
<dependency>
	<groupid>org.slf4j</groupid>
	<artifactid>slf4j-jdk14</artifactid>
	<version>1.5.8</version>
	<scope>test</scope>
</dependency>

(version 1.5.8 is required to match the api dependency in the hibernate 3.5.0-Final libraries.

Friday, 29 July 2011

Installing the Sun JDK on Ubuntu 11.04 (Natty)


sudo apt-add-repository "deb http://archive.canonical.com/ natty partner"
sudo apt-get update
sudo apt-get install sun-java6-jdk


Shamelessly ripped off from http://www.ivan-site.com/2011/07/installing-sun-java-jre-on-ubuntu-11-04/

Tuesday, 10 May 2011

memcached-session-manager and Membase

The Tomcat memcached-session-manager and Membase do play well together, but the documentation on setting it up is a bit thin, and more focused on a memcached installation, especially if you are using Membase for the bucket replica and HA.


Membase
Set up the basic N-node Membase cluster. This part is trivial. You'll end up with N servers, all running their local Moxi proxy server on port 11211. You'll be able to telnet into any of the servers on that port and set an object. Telnet to another of the servers on port 11211 and you can get the object back out.


memcached-session-manager
The tricky part is that memcached-session-manager does not want to know about the topology of the replica data buckets in the Membase cluster. Leave that job to the Moxi memcached proxy. You get Moxi when you install Membase, or it's available as a separate installer for Linux.
Run moxi on each of your Tomcat hosts (do it for HA, though you will now need to monitor the moxi process as well as your tomcat process from the load balancer - if either dies, the server should be pulled from the pool). We use port 11311 for the moxi to separate it conceptually from the moxi's running in "gateway" mode on the Membase servers on port 11211:

/opt/moxi/bin/moxi -Z port_listen=11311 \
http://192.168.0.1:8091/pools/default/bucketsStreaming/default,\
http://192.168.0.2:8091/pools/default/bucketsStreaming/default


Then in your Tomcat <Context> configuration, you use the local moxi details in the session manager:

<Manager className="..." memcachedNodes="n1:localhost:11311" ... />


What you end up with is...

Tomcat1 -> LocalMoxi --\       
                        \      /--> Membase 1
Tomcat2 -> LocalMoxi ----\    /
                          >--<
Tomcat3 -> LocalMoxi ----/    \
                        /      \--> Membase 2
Tomcat4 -> LocalMoxi --/


And each local moxi is aware of the topology of the Membase cluster, and is aware of whcich Membase servers are running and which are down. You will still get errors in your Tomcat logs from the spymemcached library if you kill a Membase server. That will continue until you take a manual step of hitting "remove" on the dead server from the remaining server's console (and then you should rebalance the cluster).

Summary
It's possible this is overkill, but until we introduced the local moxi proxy processes, our Tomcat servers would not handle a Membase server being killed.

Wednesday, 30 March 2011

Firefox 4 - don't trim the URL preview

To stop Firefox 4 from trimming the URL in the preview and loading pop-ups, edit your <profile>/chrome/userChrome.css thus:
statuspanel {
max-width: 100% !important;
}
source: http://www.lifehacker.com.au/2011/03/stop-firefox-4-from-trimming-url-previews-in-the-status-bar/

Tuesday, 29 March 2011

Firefox 4 - make the app menu transparent

To change the "Firefox" app menu from orange to transparent in Firefox 4, edit your <profile>/chrome/userChrome.css thus:
@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul); 
#appmenu-button{
    background:transparent!important;
}
source: http://www.lifehacker.com.au/2011/03/from-the-tips-box-windows-7-favorites-the-firefox-button/

Saturday, 26 March 2011

ATV2 XBMC unofficial nightlies

ssh root@apple-tv.local
cd /private/var/tmp && \
wget 'http://hadm.net/~keith/xbmc_atv2/latest_atv2.deb' && \
dpkg -i latest_atv2.deb && \
rm latest_atv2.deb

Sunday, 20 March 2011

ATV2 xbmc.log file location

Apple TV 2 XBMC's xbmc.log file is located at:

/private/var/mobile/Library/Preferences/xbmc.log

Saturday, 19 March 2011

Showing a background image while an iframe is loading

Rather than a white rectangle on your page while an <iframe> is loading, you can set a background image in CSS. This works in IE7 & IE8 (with a bit of a flash when the iframe content is ready); Firefox 3.6 and Chrome 10 (perfectly); but in Safari 5 the background image is not shown until the iframe is loaded.

I found this useful when 'co-branding' a site to use another site's header and footer in an iframe. Since I could not trust the speed of the other sites, I grabbed their logo, then positioned it as a background image on the iframe so the logo was in the same position as the final iframe version. Then at least the user sees a nice logo straight away, and they might need a second or two before the navigation and other elements of the other sites headers show up.

This was the iframe code:
<iframe width="960" height="154" scrolling="no" frameborder="0"
marginwidth="0" marginheight="0" src="[other-site-URL]"
style="background:url('[local-logo-URL]') no-repeat scroll [X-off]px [Y-off]px;"></iframe>