Add Scroogle to your search area in Firefox 2.0 Install the 'Scroogle Scraper' search plugin.

firefox-girlThe browser war isn’t a real war with machine guns and artillery shells and breaking Geneva conventions, it’s more of a virtual turf war for the world’s web surfers. Let’s review the history of this nifty interweb of ours:

  • 1989: CERN researcher Tim Berners-Lee launches the first web server*. You can see that web server (and I have) because it’s just sitting on a table in one of the CERN lobby buildings. You could even steal it if you wanted (I considered it), because there is very little security– those silly Swiss!
  • Mosaic, the first graphical browser, came out a few years later, in 1993, followed by it’s cousin Netscape Navigator in 1994. Remember?
  • Microsoft, with their market-busting, monopolistic fervor, introduced Internet Explorer (IE) in 1995 and began shipping it with all version of Windows. Because it came pre-installed, it quickly grew to near complete market domination.
  • SEVEN YEARS passes with little change. Everyone had been using IE. Then, WHAMMO! Firefox (www.getfirefox.com). Firefox is available on Linux, Mac and PCs. It’s fast, has lots of awesome plugins and TABS!
  • A year or so passes and Microsoft plays catch up and finally releases a tabbed version of IE. Other browsers appear (like Google Chrome.)

browser_warHow goes the fierce, non-violent, nerdy war? As of May 2009, the browser market share looks like:
IE7 21.3%
IE6 14.5%
IE8 5.2%
FF 47.7
Chrome 5.5%
Safari 3.0%
Opera 2.2%

So, what’s the next step? Better tabs. So good ol’ Mozilla (makers of Firefox) are having a competition to redesign the tabbing experience.

My good buddy, Grady, a world-class graphic designer, has created a new paradigm for tabbing, he calls it favitabs, (http://www.favitabs.com). Today starts the voting for the people’s choice award, and anyone can vote: http://design-challenge.mozilla.com/summer09/showcase.php

The voting ends of July 5th, so if you want to be part of history, if you think Favitabs is an awesome idea, then click on over to the design challenge and vote.

* Sir Tim also came up with the crazy http:// prefix for web addresses. He is said to regret that decision.

If you’re like me, and goodness who isn’t?!?, you probably run a few high bandwidth sites. You probably worry a lot about reliability and scalability and fault tolerance. You’ve maybe looked into hardware load balancers (like F5’s BigIP), only to be discouraged by the hefty price tag: 15k and up. Don’t misunderstand– if you’ve got the cash, you can’t beat the BigIP in terms of reliability and features and ease of use. But if your blog isn’t exactly paying for itself yet, you’ll need to consider other options. A lot of people like the idea of DNS load balancing. That’s where you add a bunch of A records for your domain to different IP addresses. The DNS server will then serve out the IPs in a round-robin sort of manner. It’s a good way to spread the web traffic to a group of web servers. But if a server goes down, you’ll have to remove it from your DNS and wait for the TTL to expire before things are back up (of course, you could power down the machine and alias the IP address to another server in the same network…)

But it’s clunky because the only balancing is round robin and there are no health checks involved. Fortunately, you have alternatives. I’ll present one of those options here: load balancing with mod_proxy. mod_proxy is an apache module. In the diagram to the above-right you can see my setup. I have two load balancers, two web servers and two databases. On the two load balancers, I’m running apache with the mod_proxy and mod_proxy_balancer. There is a UDP heartbeat between the two. Apache is started on only one of those servers and the virtual IP (VIP) is aliased to that one. If that machine goes off line, the second load balancer will grab the VIP and start up apache.

And then we have the web servers. The active load balancer will round robin serve up pages to the web servers. If one of the web servers goes off line, the load balancer detects that and will take that web server out of the rotation.

And, yes, I set it all up and it works splendidly. Yes, you can put the load balancers and web servers on two machines instead of four. Yes, you’ll need to keep sessions in MySQL to prevent loss of session info during a failover. You can check which load balancer is active by watching ifconfig or ps -aux|grep httpd. If things aren’t working, check /var/log/ha-log, and if there are errors, it will tell you the command it’s trying to run. run that command to see the error message.

I haven’t talked about how to scale the MySQL tier. There are a number of solutions: master/slave, mysql proxy, active/active or mysql cluster. More about that later.

There are a number of conf files you’ll need to set up to get this working:

authkeys

auth 2
2 sha1 TOPSECRETWORD

ha.cf

logfile /var/log/ha-log
bcast eth0
keepalive 2
warntime 5
deadtime 10
initdead 20
udpport 694
auto_failback yes
node lb1
node lb2
uuidfrom nodename
respawn hacluster /usr/lib/heartbeat/ipfail

haresources (Must be EXACTLY the SAME ON BOTH lb1 and lb2!!!)

lb1 10.1.1.19 httpd

http.conf

Listen 10.1.1.19:80
…
ProxyRequests Off
 
<Location /balancer-manager>
SetHandler balancer-manager
Order deny,allow
Allow from all
</Location>
 
<Proxy balancer://mycluster>
# cluster member 1
BalancerMember http://10.3.1.31:80 route=lb1
# cluster member 2
BalancerMember http://10.3.1.32:80 route=lb2
</Proxy>
 
ProxyPass /balancer-manager !
ProxyPass / balancer://mycluster/ lbmethod=byrequests
ProxyPassReverse / http://10.3.1.31
ProxyPassReverse / http://10.3.1.32
#ProxyTimeout 10
 
<VirtualHost *:80>
ServerName intranet.example.com
UseCanonicalName On
 
DocumentRoot /var/www/html
<Directory "/var/www/html">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
 
RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^(127.0.0.1)
RewriteRule ^(/server-status) $1 [H=server-status,L]
 
# Proxy the rest to the load balancer
RewriteRule ^/(.*)$ balancer://mycluster%{REQUEST_URI} [P,QSA,L]
 
ErrorLog /var/log/httpd/http_log_error
CustomLog /var/log/httpd/http_log combined
 
# Deflate
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/javascript text/css
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch bMSIE !no-gzip !gzip-only-text/html
 
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
</VirtualHost>

iptables

...
-A RH-Firewall-1-INPUT -m state –state NEW -m udp -p udp –dport 694 -j ACCEPT
…

ldirectord.cf

checktimeout=10
checkinterval=2
autoreload=no
logfile="/var/log/ldirectord.log"
logfile="local0"
quiescent=yes
 
virtual=10.1.1.19:80
       fallback=127.0.0.1:80
       real=10.1.1.21:80 masq
       real=10.1.1.22:80 masq
       service=http
       request="index.html"
       receive="Test Page"
       scheduler=rr
       protocol=tcp
       checktype=negotiate

These reference pages are very useful:

The open position is for a senior technical engineer. Requirements include a bachelors in CS or IT and 5 years experience in enterprise development.

I got a resume today from an individual applying for the position, with the following:

Skills & Training:

  • Hostage Negotiations Training
  • Security Officer Basic Training Course
  • Tactical Site Survey team member
  • Massage Therapy Training
  • Electrocardiograph Technician
  • Survivalist & Emergency Preparedness Instructor
  • Primitive Skills Specialist (bow making, pottery, tanning, weaving, etc )
  • Published a fishing news letter and report that I emailed to over 200 people

Interests:

  • Singing and song writing
  • Studying plant, animal, survival, and medical reference materials
  • Martial arts and weapons study
  • Ancient weapons collecting
  • Handicrafts (leatherworking, woodworking, metalworking)
  • Writing poems and stories

I’ve been interviewing technical people for an open support engineer position these last few weeks. As a consequence, I’ve scanned through at least a hundred resumes, searching for good candidates. Today I found these two lines on a resume and I thought I’d include them below for your benefit:

(under Expertise/Certifications)

  • Programming Languages: BASIC (similar to C++), PERL, C++, ObjectRexx
  • Database web programming (WEBWIZARD)

Thoughts?

write a pseudocode function that implements the following:

  • when passed in a number that is evenly divisible by 3, return “wiz”
  • when passed in a number that is evenly divisible by 5, return “bang”
  • when passed in a number that is evenly divisible by both 3 and 5, return “wiz bang”
  • otherwise, return the number passed in

here are two solutions:

string function DumbWizBangCheck(int number)
{
	string output=‘’;
	if (number%3==0) output=‘wiz’;
	if (number%5==0) output=‘bang’;
	if (number%5==0&&number%3==0) output=‘wiz bang’;
	if (output==‘’) output=(string) number;
	return output;
}
string function BetterWizBangCheck(int number)
{
	if (number%15==0) return ‘wiz bang’;
	if (number%3==0) return ‘wiz’;
	if (number%5==0) return ‘bang’;
	return (string) number;
}

Maybe you’re thinking you’d like to cut stuff out of a big piece of plastic. or metal. or wood. You’d like a computer controlled milling machine. Well, you could go out a buy a ready-made version for a few thousand, but that would be ENTIRELY too easy. You’d like to build your own, wouldn’t you?

Part list:

  • Two-Speed Variable Bench Mill/Drill Machine — $621.23 (harborfreight.com)
  • Mini Mill CNC kit #4 — $559.00 USD (cncfusion.com)
  • CNC 3 Axis Package with 425 oz-in motor and KL-4030 Bipolar Driver with 36V /8.8A Power Supply — $404.49 (kelinginc.net)
  • Male-male 25 pin parallel cable
  • Hookup wire, 12 gauge & 18 gauge (radioshack)
  • Mach3 and LazyCam software — $150.00 (machsupport.com)
  • Starter Kit, Mini Mill — $79.95 (littlemachineshop.com)
  • Heat shrink tubing
  • Plastic wire tubing
  • Die grinder $20

Steps:

  1. Install CNC kit onto Mill
  2. Install/wire CNC 3 Axis package
  3. Configure Mach3 software

Useful reading: http://littlemachineshop.com/info/MiniMillUsersGuide.pdf

thx, xkcd

Recently I found myself in an uninspiring company meeting listening to a consultant drone on about what he felt were essential elements of successful software companies. He and I had both been hired to help this small, struggling company reverse its declining profits. The last thing I remember before I fell asleep was his blathering about the lessons he learned from the dozens of companies he had helped bury.

I’m not normally a cynic and I recognize it’s easy to dismiss others’ ideas as out-of-touch or impractical to implement. Pointing out deficiencies is not hard at all. A colleague of mine once reminded me that the burden of the complainer is to propose viable solutions to the problem.

Now, unlike the speaker, I was hired for tactical consulting, not strategic, but I thought of what I might be able to say in front of these twenty five developers, sales reps and customer support engineers. What are the core principles of great software companies?

Back in my MBA classes at the University of Utah, I concluded that it’s impossible to provide a formula that guarantees business success; there are just too many non-deterministic factors at play (timing, market conditions, actions of competitors, etc.) It is possible to list the common elements of thriving companies and to highlight the pitfalls you must avoid. Here is a brief list of some elements and principles I’ve found to be in place at great software companies:

Robust Software Framework

  • Reusable code/modules
  • Object oriented architecture
  • Services oriented architecture (interconnectable)
  • Error handling
  • Debugging
  • Profiling
  • Database abstraction

Well Structured Environment

  • Version control
  • Code to tests
  • Ticketing system
  • CMM/ITIL process management
  • Clear release process

Cultural Values

  • Mutual accountability
  • Productive conflict
  • Trust
  • Where possible, Keep It Simple
  • Work ethic
  • No hackery– be proud of code
  • Document! (all knowledge: code, methodologies, systems, etc)
  • Always add value
  • Don’t reinvent wheels (unless it’s a much better wheel)
  • Use standards where they make sense
  • Data security and backups, anticipate hackers

Misc

  • Under promise, over deliver. on time.
  • Customer-driven features
  • Quality Assurance with automated tests
  • Fast, Clean, Simple, Intuitive interface that just works
  • Fast/Agile
  • Scalable, Fault-Tolerant Architecture
  • Team-oriented
  • Hire and retain excited, passionate people
  • Growth focused

What did I miss? Would my presentation have been as lame as the one I fell asleep in? :)

so, the question goes a-like-a this: write a function that, given an array of strings, will return the number of those strings that contain the letters c,h,e,v,r,o and n in that order. there may or may not be other letters around and in between. Here’s was my first attempt:

$strings = array(
                 "i like cheetos, but everyone knows cheez-its are better",
                 "che guevara was born in argentina",
                 "i own a chevrolet",
                 "hello world"
                 );
 
echo(chevronMatch($strings));
 
function chevronMatch($strings)
{
  $chevron="chevron";
  $chevronCount=0;
  foreach($strings as $testString)
  {
    $hitCount=0;
    for($y=0;$y<strlen($testString);$y++)
    {
      if ($testString[$y]==$chevron[$hitCount])
      {
        if ($hitCount<strlen($chevron)-1)
        {
          $hitCount++;
        }
        else
        {
          $chevronCount++;
          break;
        }
      }
    }
  }
  return $chevronCount;
}

Obviously, iterative code like that would make a regex guru like bj upset. here’s my second attempt, this time with ereg

function chevronMatch($strings)
{
  $chevronsMatched=0;
  foreach($strings as $string)
    {
      $chevron=array(‘c’,‘h’,‘e’,‘v’,‘r’,‘o’,‘n’);
      $regex="[a-z,- ]*";
      $regexString=$regex.implode($regex,$chevron).$regex;
      if (ereg($regexString,$string)) $chevronsMatched++;
    }
return $chevronsMatched;
}

Maybe you want to create some cool new UI using an actual slider (i.e., a variable resistor) to control something (like motor speed.) Well, that’s where the ADC0838 comes in. Below is some Parallax Spin code that will read in data on the first channel of that chip (and display the value back over a serial connection.) The chip actually has eight channels (you select which one you’re interested in through the built in MUX), but this code is hardwired, so to speak, to just read the first one.

Notes:

VCC, VDD mean + voltage
VSS is Ground

connect Vref (chip pin 12) to +

test 5v input: + to CH0 (chip pin 1)

SE bar (chip pin 13) to gnd

ground COM (Chip pin 9) for single ended

tie Agnd (Chip pin 11) to gnd
tie Dgnd (Chip pin 10) to gnd

ADC0838 8-Channel Mux
 CH0 +-1-|___|-20-+ Vcc
 CH1 + 2       19 + V+
 CH2 + 3       18 + CS bar
 CH3 + 4       17 + DI
 CH4 + 5       16 + CLK
 CH5 + 6       15 + SARS
 CH6 + 7       14 + DO
 Ch7 + 8       13 + SE bar
 COM + 9       12 + Vref
Dgnd +-10------11-+ Agnd

Single Ended MUX Mode (table 2)
SGL/DIF bar is 1
ODD/SIGN is 0
Select 1 is 0
Select 0 is 0

Setup (address MUX)
1- CS bar goes low
2- Start pulsing CLK (data read on rising edge), while sending data into DI
Rising 1
Start Bit: 1
Rising 2
SGL/DIF bar: 1
Rising 3
ODD/SIGN: 0
Rising 4
Select Bit 1: 0
Rising 5
Select Bit 0: 0
Output
1- CS bar stays low
2- pulse CLK while reading data on DO on falling edge
Falling 1..7
MSB 7..1
Falling 9..13
LSB 1..7

Here’s the SPIN code:

'**********************************
'*    ADC 0838 Channel 0 Debug    *
'**********************************
 
'adapted from Bryan Kobe June
 
CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
 
' pin configuration
 
  clk     = 1
  cs      = 0
  dataout = 2
  datain  = 3
 
'P0: CS bar (chip pin 18)
'P1: CLK (chip pin 16)
'P2: DO (chip pin 14) [data out from the chip to the propeller, its an INPUT to the propeller]
'P3: DI (chip pin 17) [data from propeller TO the chip, its an OUTPUT from the propeller]
 
OBJ
  bs2   : "BS2_Functions"
  debug : "FullDuplexSerial"
  num   : "Numbers"
 
VAR
  byte ADC             ' Analog to Digital Channel Din Value.  Set using CON values.
  long datar           ' 8 Bit return value from conversion
 
PUB main
  dira[cs]~~         'set Chip Select to output
  outa[cs] := 0      'set Chip Select bar to low
  dira[clk]~~        'set clk pin to output
  outa[clk]:=0       'set clock pin low
  dira[datain]~~       'set DI data in pin to an output
  dira[dataout]~      'set DO data out pin to an input
 
debug.start(31,30,0,57600)
   debug.str(string("ADC0838 Channel Debug"))
 
repeat
  debug.str(string("Ch.0 = "))
  debug.str(num.ToStr(GetADC(0), Num#dec))
  waitcnt(5_000_000 + cnt+50000)
 
 
PRI GetADC( chan ) : value
  ADC := %11000          ' channel 0
  datar := write(ADC)    ' write MUX Address to start conversion for ADC channel and set result to the datar value
  return datar
 
PRI write( ADCaddr ) : ADC_value
  outa[cs] := 0                                         'set Chip Select bar LOW, activating the ADC chip
  bs2.SHIFTOUT(datain, clk, ADCaddr, BS2#MSBFIRST, 5 )  'shift out the addressing byte to the ADC via DI pin on ADC
  ADC_value := bs2.SHIFTIN(dataout, clk, BS2#MSBPOST, 8 ) 'shift in the byte from the ADC via the DO pin on the ADC
                                                        'the first byte is a start bit, to initiate reading sequence
  outa[cs]:=1                                           'set Chip Select bar HIGH, de-activating the ADC chip
  return ADC_value                                      'return value of the ADC

Next Page »

Send to a friend * Print this page * Join the club * Talk with my robot * Advertise here * Search this Site * Donate * Link to me


Web hosting by Utah Hub *  Powered by CreativeTap *  In association with Segomo
Unless otherwise noted, Copyright 2004-2006, Ryan Byrd. All Rights Reserved.
Ryan Byrd dot net -- probably the coolest site in Utah