Capistrano worked, have to make development match

Continuing to learn Capistrano, I have to make my development environment match.

My dev environment is Ubuntu 10.0.4 and a number of Gems are more recent versions than those on Site5, I have to get my dev environment to match the now, working production site better so that deployments with Capistrano can really be just a push of a button. Comparing the Gemfile on the host and my local one showed that I use mysql2 on host and sqlite3 on dev. The first thing to do is to get mysql2 onto my dev machine.

In my dev Gemfile I remove sqlite3 and add mysql2.

source ‘http://rubygems.org’

gem ‘rails’, ‘3.0.9’
gem ‘mysql2’, ‘~>0.2.7’
gem ‘rake’, ‘0.8.7’

Executing ‘bundle install’ brings me this:


Using activerecord (3.0.9)
Using activeresource (3.0.9)
Using bundler (1.0.15)
Installing mysql2 (0.2.13) with native extensions/usr/local/lib/site_ruby/1.8/rubygems/installer.rb:551:in `build_extensions’: ERROR: Failed to build gem native extension. (Gem::Installer::ExtensionBuildError)

/usr/bin/ruby1.8 extconf.rb
checking for rb_thread_blocking_region()… no
checking for mysql_query() in -lmysqlclient… no

The bold bits show the bundler error attempting to install mysql2 and all the error information that comes after it is a bit of a canard. The problem is that a few libraries are missing. Execute this sudo will supply those libraries:

sudo apt-get install libmysql-ruby libmysqlclient-dev

This should succeed and when it does reissue the ‘bundle install’. This time is should work.

The next problem is ‘rake’, is you issue rake by itself you get:

$ rake
rake aborted!
You have already activated rake 0.9.2, but your Gemfile requires rake 0.8.7. Consider using bundle exec.

(See full trace by running task with –trace)

The problem is that the active rake is 0.9.2 but the one I want to run is 0.8.7. Stay tuned.

Web surprise – the long tail for paper notebook lovers

I am always so surprised when I find that other people enjoy or love the same things I do and notebooks are my surprise for the day.

I currently write in a Gibson Markings notebook that I bought from Staples on sale and I bought a few more at the price for the future. Noodling around the web today looking for sellers of these fine little notebooks I stumbled on a few websites devoted to finding the perfect little notebook. Sites as in more than one site? Yes, that’s right there are a whole slew of sites devoted to this one topic. The long tail strikes again.

Here are a few of the sites and each have a review generally with pictures about a myriad of small note books.

http://www.notebookstories.com/
http://meredictum.wordpress.com/2007/07/18/moleskine-alternative-cr-gibson-markings-notebooks/
http://blackcover.net/

My wonder never ceases, the net really allows people to bring their interests into public view. I am amazed.

Debugging WCF services in the cloud (the worst case scenario)

I’ve had WCF services running on in-house computers exposed to the Internet for some time. Moving a web service from an in-house fully accessible computer environment to a web hosting environment like GoDaddy, HostGator and others that limit your access is a challenge when troubleshooting the service. Here’s what I did when everything looked like it should work but didn’t. Calling out to a contract returned… nothing. No data, no errors, nothing. This article only covers this one narrow case debugging WCF in the cloud, other articles will cover other techniques for other problems.

To understand the service it’s hosted on IIS 7.0 running over http (for debugging purposes) and https, .Net 4, has a handful of contracts, and uses a database hosted as well on the ISP. Architecturally it’s a simple database application in the cloud. I have the service working fully on my development environment and need to replicate it at the ISP. Data access is through stored procedures at the database and the interface on the code side uses Linq.

Linq is not an issue with hosting parameters as I’ve laid out, you could just as easily use Entity Framework, ADO.NET and other technologies to access the stored procedures.

First thing to do is get the database working correctly. The hosting service has some means of creating and uploading existing database for your use, GoDaddy which is where this service is hosted has a means, other ISPs do too. I assume you’ve verified through some means that the database is deployed and operational. With stored procedures, you’ve called them and verified that they are working, your credentials and accessibility works and you are ready for the WCF part.

Second, upload your WCF service through the FTP mechanism or better yet through Visual Studio’s publishing wizard. Now, one thing to include in the service if you haven’t is a contract that returns a simple string, a version number, without interacting with the database. You call this contract to verify that WCF is working without needing the database. This is a simple and effective sanity check. I always include a version number contract in my services for this purpose and as a means of identifying the revision of the service.

 

namespace Service.ServiceContracts
{
    public partial interface IServiceContract
    {
        [OperationContract(Action = "http://polymorf.com/2010/01/ServiceContract/Version"]
        Service.MessageContracts.VersionResponse Version();

    }
}

namespace Service.MessageContracts
{

    [MessageContract(IsWrapped = false)]
    public partial class VersionResponse
    {
        private string versionResponseField;

        public string versionResponse
        {
            get { return versionResponseField; }
            set { versionResponseField = value; }
        }
    }
}

 

This contract returns a string wrapped in a class from the service, the string contains a manually set version number, not a dynamically set value. You need to know that a string constant is what will be returned from the service. You will understand this shortly.

The implementation of version() is

public override Service.MessageContracts.VersionResponse Version()
{
    VersionResponse response = new VersionResponse();
    response.versionResponse = "002";
    return response;
}

Test 1 – Use a web browser and navigate to the web service root page (where  the .SVC file is).

Does the page appear on the browser? If not, what does the error message say? Have you turned off custom errors while you are troubleshooting? Do not proceed further until you’ve got the service functioning at the most basic level.Anything else is pointless. The service page has to appear correctly and the WSDL page (click on the WSDL link) has to appear correctly. If not, you have a fundamental problem and go fix it. Once it works,

Test 2 – Execute the version contract.

Using a tool like SoapUI or Visual Studio’s WCFTestClient you test this contract. You should get back the version string you expect. If not, why not? Did your service timeout? Did your service indicate there is an argument problem meaning the string type in the response is not the right type?

Local testing of your service enabled you to have confidence that your service for just this one contract was  correct. The likely cause of problems at this point are: something in the web.config, the wrong app pool on the hosting service (you need .Net 2.0 and it’s set to .Net 4.0 or vice-versa), or you are calling the wrong service/contract. If there is a fault message you have to fix the problem (other articles of mine will cover various problems), if there is no message and not returned content you have to retrace your code. Is your contract working locally (on your development environment)? The version() contract returns a string constant (earlier I said I would make this clear) and this is why. If you dynamically create the version string, whatever means of construction you take may be the culprit and not the service. If the string is a constant you know it’s just the service and not your means of building the string. At this point it’s just checking your work – right service, right contract, local testing proves this works, you’ve attended to any fault message. If all this is proved out and correct your service will work. If not, let me know a condition where it still does not.

Test 3 – Execute a simple database-backed contract.

Here’s where the rubber meets the road. Either select retrieval contract, something that with minimal arguments forces the database to retrieve some data or create a contract for this purpose. The one case of interest in this article is a properly formatted request to retrieve data returns nothing at all. No errors and no data. Other cases where you receive a fault string or the data is wrong are not the point of this article. Those failures can be dealt with in a variety of ways but good input and no output is infuriating. The ISP won’t let you debug the service in the way you are use to, running a debugger, so what do you do? Here’s my line attack.

Suspect the database connection first. You’ve already proven that the service fundamentally works with the first steps. Now you’ve added a database interaction into the mix so it’s the likely cause of the problem. Create a simple ASPX web page that can query the database just like the service would. The page can be the most simplistic thing imaginable – enter a value, hit SUBMIT and get back results. You have to use the same stored procedure that you contract test uses. This is important. Don’t create an alternative means of retrieving the data. This is where you can mislead yourself – always use the same path in troubleshooting. Create the page, test it locally, publish it and test with it. What happens? Does it return the sample  data? If not why? If it does return the data correctly and the contract does not, it’s likely that your service reference to the database is wrong. Find all the references the service uses (.dbml files, property settings, and your code) and find the problem there. There has to be a place in the code that the connectionString is pointing to the wrong location.

The following aspx page and code-behind assumes in the web.config there is a connection string named ‘ProductConnString’.

DebugPage.ASPX

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DebugPage.aspx.cs" Inherits="DebugPage" Debug="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%
foreach (string item in DebugResults)
{
Response.Write(item);
Response.Write(”
“);
}
%>

DebugPage.aspx.cs (code-behind)

//#define DEBUG
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;

public partial class DebugPage : System.Web.UI.Page
{
    public string Date {
        get { return (string)Session["Date"]; }
        set { Session["Date"] = value; }
    }

    public List DebugResults = new List();

    // Write messages to the page.
    protected void MSG(string msg)
    {
        Response.Write(msg + " | ");
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        MSG("Page load");
        Date = Request["DateValue"];

        // Fetch the data on the retun trip to the client.
        if (IsPostBack)
        {
            MSG("after IsPostBack");
            if (string.IsNullOrEmpty(Date))
                return;

            MSG("after Date check");
            SqlConnection conn = null;
            SqlDataReader rdr = null;
            string connString =
                System.Configuration.ConfigurationManager.ConnectionStrings["ProductConnString"].
                    ConnectionString;

            // create and open a connection object
            conn = new
                SqlConnection(connString);
            conn.Open();

            // Setup the call to the sproc 'GetAllFor'.
            SqlCommand cmd = new SqlCommand("GetAllFor", conn);

            cmd.CommandType = CommandType.StoredProcedure;

            string startDate = Date;
            string endDate = Date;
            int ascending = 1;

            cmd.Parameters.Add(new SqlParameter("@StartDate", startDate));
            cmd.Parameters.Add(new SqlParameter("@EndDate", endDate));
            cmd.Parameters.Add(new SqlParameter("@asc", ascending));

            DebugResults.Clear();

            MSG("before ExecuteReader");

            SqlDataReader r = cmd.ExecuteReader();
            while (r.Read())
            {
                int id = (int) r["id"];
                DateTime date = (DateTime) r["datetime"];
                string action = (string)r["action"];
                string description = (string)r["description"];
                string result = id.ToString() + "(" + date + ") " + action + " : " + description;                
                DebugResults.Add(result);
            }
            r.Close();

            conn.Close();
        }
    }
}

Sample run

Page load | after IsPostBack | after Date check | before ExecuteReader |
Enter a date

  3212(7/15/2011 7:31:08 AM) IN :
3213(7/15/2011 10:43:22 AM) OUT :
3214(7/15/2011 11:16:37 AM) IN :
3215(7/15/2011 12:00:00 PM) OUT :
3216(7/15/2011 1:29:48 PM) IN :
3217(7/15/2011 5:57:39 PM) CP : Left off – https wsdl fails import with ‘cant find soap1.1’ in SF
3218(7/15/2011 5:57:45 PM) OUT :

What’s important here is that the debug messages appeared and the data retrieval worked. If this page works but your service doesn’t, it’s the database connection or connectivity. It’s just that simple. You have to hunt down the place in your service that you’ve referred to the database in the wrong way.

Moving my company sites and activities into the “cloud”

I have several services that I’ve been using for years both of my own creation and some ope-source and I needed to move them onto a hosting provider. It just didn’t make sense to continue to host these things myself any more and I’ve been doing it a long time.

Which provider, what features and how to do it?

After looking at HostGator, Westgate, and others I selected GoDaddy surprisingly enough.

This is a test entry.

Move one step to the right to get better phone reception – why?

I’ve always wondered why mobile phone reception varies as you walk around. Stand in one place and you’ve got 5 bars, move to the right a step or two and you don’t. Reading Wireless Communications by Molisch provided the answer in the first 20 pages. Simply put, your signal is broken up between several pieces that come to your phone from different paths (multipath) and therefore at slightly different times (out of phase). At your phone they arrive to add together or subtract from each other. If they add together you have strong reception and if the subtract from each other you have weak reception.

Since the actual length of the signal is about 1m, when the multipath signals arrive at 1/2 the wavelength away from you (0.5m or about 1.5 ft)  you can experience a vastly different signal strength better or worse.

Multipath

Copyright www.intechopen.com

In this picture, BS  (base station) broadcasts signal meant for the phone. The signal reflects off buildings, gets scattered through trees and defracts through other buildings. The signals in this case are coming from different directions and are of different lengths. Your phone has to add them together to make one big signal but the slight delay on some of the signals from others forces the total signal received to be less than what was transmitted.

Now you have the answer.

P.S. Could this be improved now? Practically speaking, no, since improvements would require much more processing power which will enlarge the phone handset and require a bigger battery. In the future the answer is maybe. Research continues all the time on this problem so it is likely that multipath signal noise will be reduced further. No garentees however it is likely.