Who we are

We are the developers of Plastic SCM, a full version control stack (not a Git variant). We work on the strongest branching and merging you can find, and a core that doesn't cringe with huge binaries and repos. We also develop the GUIs, mergetools and everything needed to give you the full version control stack.

If you want to give it a try, download it from here.

We also code SemanticMerge, and the gmaster Git client.

Setting up a fallback server using replication

Friday, March 20, 2009 Pablo Santos 0 Comments

to work under a wide variety of scenarios.

Normally when you think about distributed you inmediately jump into the situation where each developer has his own repository and replicates changes back and forth with his peers or a central location (or the one with highest rank in the meritocracy if you prefer :-P).

But today I'm going to talk about a slightly different set up.

What if you need to have redundant servers so in case one goes down you can inmediately recover and all developers (normally in a big shop) can continue working with the fallback machine?

Well, Plastic has several ways to solve this problem (you know, we're flexible!):


  • The first one involves taking advantage of one of its supported backends and implement a mirrorer database with MySql or SQL Server. It is adequate when you've seasoned dbas at home, who are already doing the same stuff on a daily basis for their corporate servers.
  • And the second option, the one I'll be explaining today, relies on the distributed system to implement an equivalent behavior.

    The following figure depicts the situation.



    Ok, how can we set up this with Plastic?

    First you obviously need a couple of servers, one you're already using on a daily basis and then a second one (probably a clone of the first one), also running Plastic. In order to make things easier to understand, the first server will be called dragon and the second one pendergast.

    dragon will be hosting the master repository and pendergast a second one, named replica, which will be a clone of master.

    Note: needless to say servers could be running on different operating systems and even using different database backends.

    Once the servers are up and running, the procedure will be really simple:
  • Locate which branches to replicate
  • Replicate them
  • Run the process repeteadly (e.g. once an hour)

    So, how can we identify which branches deserve our attention and have to be replicated? Easy: we need to know where are the changes made since the last replication, don't we?

    And, how can we know what changes have been done and where? Look at the changesets view and click on the advanced button, as shown in the following picture.


    Plastic SCM supports fully distributed development and hence it is flexible enough

    Plastic implements a powerful sql-like query system.

    Most of the views in the Plastic GUI retrieve their data from a Plastic query, and changesets view is one of them. So we just have to take a look to the default query to figure out what do we need.

    In fact, the detailed process to follow is drawn here, including the replication commands to use.



    We will be using a command like the following

    $ cm find changesets where date >= ‘2009/03/18  19:30:00’ --format={branch} --nototal


    To find changes and:

    $ cm replicate br:/main/task00X@master@dragon:9090 replica@pendergast:7074


    to replicate.

    Here's the ruby code I used for my replication script:

    if ARGV.size < 2
        puts "Usage: synchservers srcrepspec dstrepspec"
    end
    
    srcrep = ARGV[0]
    dstrep = ARGV[1]
    
    # find all changes since last replication (one hour)
    
    date = Time.new - 60*60
    
    branchescommand = sprintf(
        'cm find "changeset where date >= \'%s\'" --format={branch} --nototal on repository \'%s\'',
        date.strftime('%Y/%m/%d %H:%M:%S'), srcrep )
    
    output = `#{branchescommand}`
    
    # build an array of branches
    
    branches = Array.new
    
    output.each { |branch| branches << branch.chomp}
    
    # run removing duplicates
    
    branches.uniq.sort.each { |branch| 
        replicatecmd = sprintf(
            'cm replicate br:%s@%s rep:%s',
            branch, srcrep, dstrep);
        puts replicatecmd
        system(replicatecmd)
    }
    


    Easy?

    In order to run it you just have to:

    $ synchservers.rb master@dragon:6060 replica@pendergast:9090


    And include it as a cron or scheduled task.

    Enjoy!
  • Pablo Santos
    I'm the CTO and Founder at Códice.
    I've been leading Plastic SCM since 2005. My passion is helping teams work better through version control.
    I had the opportunity to see teams from many different industries at work while I helped them improving their version control practices.
    I really enjoy teaching (I've been a University professor for 6+ years) and sharing my experience in talks and articles.
    And I love simple code. You can reach me at @psluaces.

    0 comentarios: