Cogs and Levers A blog full of technical stuff

How to setup an oplog on a single MongoDB instance

The MongoDB oplog allows you to keep track of changes that have happened on your database in real-time. This is a very useful tool that isn’t offered out of the box with a single server instance. You can follow these steps to enable to oplog on a standalone MongoDB instance.

Un-comment the following lines from your /etc/mongodb.conf file

replSet=rs0
oplogSize=1024

This will give your MongoDB server a replica set identity of rs0 and will allow your oplog to grow to 1024mb. You can tune these parameters to suit.

To complete the process, restart your MongoDB daemon and open a shell. You just need to issue rs.initiate() on the local database:

michael@mongo:~$ mongo
MongoDB shell version: 2.6.1
connecting to: test
> use local
switched to db local
> rs.initiate()
{
   "info2" : "no configuration explicitly specified -- making one",
   "me" : "mongo:27017",
   "info" : "Config now saved locally.  Should come online in about a minute.",
      "ok" : 1
   }
> show collections
me
oplog.rs
startup_log
system.indexes
system.replset

You now have the oplog available to you.

Assembly Syntax Intel & AT&T

This post is just a little cheat sheet for myself on Intel & AT&T syntax.

A useful table mapping some simple instructions between the two syntaxes linked through from the GCC-Inline-Assembly-HOWTO:

Intel Code AT&T Code
mov eax,1 movl $1,%eax
mov ebx,0ffh movl $0xff,%ebx
int 80h int $0x80
mov ebx, eax movl %eax, %ebx
mov eax,[ecx] movl (%ecx),%eax
mov eax,[ebx+3] movl 3(%ebx),%eax
mov eax,[ebx+20h] movl 0x20(%ebx),%eax
add eax,[ebx+ecx*2h] addl (%ebx,%ecx,0x2),%eax
lea eax,[ebx+ecx] leal (%ebx,%ecx),%eax
sub eax,[ebx+ecx*4h-20h] subl -0x20(%ebx,%ecx,0x4),%eax

Some important points to note:

  • Source and destinations are flipped in opcodes.
    • Intel is dest, src
    • AT&T is src, dest
  • AT&T decorates registers and immediates
    • Registers are prefixed with a “%”
    • Immediates are prefixed with a “$”. This applies to variables being passed in from C (when you’re inline).
  • Intel decorates memory operands to denote the operand’s size, AT&T uses different mnemonics to accomplish the same.
  • Intel syntax to dereference a memory location is “[ ]”. AT&T uses “( )”.

xargs -i

This post is a just a tid-bit for the use of xargs in bash.

If you can get a list of work to do from a file or stream, you can pipe these into xargs to do further work. An example of this, I’ve taken from here. This will find all of the *.bak in or below the current directory and delete them.

find . -name "*.bak" -type f -print | xargs /bin/rm -f

Extending the usage of xargs to incorporate the -i switch, you can replace “{}” with the line of text read in the preprended command.

cat url_endings | xargs -i wget "http://somewhere.com"

In this command, it’s expected that the file “url_endings” would be data that looks like this:

/files/first
/files/second
/files/third
etc . . 

A Quick Lap with MVar

Introduction

Concurrent programming is hard. It’s made a lot easier with good tools and MVar is one of them. MVars is just a location for a value. It can contain a value or contain nothing and the API will block accordingly, providing a safe concurrent programming environment for mutable state.

From the Hackage page for Control.Concurrent.MVar:

An MVar t is mutable location that is either empty or contains a value of type t. It has two fundamental operations: putMVar which fills an MVar if it is empty and blocks otherwise, and takeMVar which empties an MVar if it is full and blocks otherwise.

Key Points

  • newEmptyMVar creates an MVar that has no value to begin with
  • newMVar creates an MVar that has an initial value
  • takeMVar returns the current value of the MVar. It’ll block until the MVar contains a value
  • putMVar puts a value into the MVar. It’ll block until the MVar doesn’t contain a value

An Example

import Control.Concurrent
import Control.Concurrent.MVar
 
main :: IO ()
main = do
	-- create an empty mvar
	m <- newEmptyMVar
	-- get another thread to put a value in it
	forkIO $ putMVar m "A value"
	-- take the value
	x <- takeMVar m
	putStrLn x

A Quick Lap with Lens

Introduction

When working with complex data structures in Haskell, burying down to observe a piece of information can be tedious. The Lens library has been created to ease this problem. From the Lens wiki page:

Lenses are composable functional references. They allow you to access and modify data potentially very deep within a structure!

The Lens library allows you to interact with your data structures in a composable manner, making your code easier to understand - and more fun to write.

Key Points

  • Whilst there are a lot of different functions, (^.) allows you to get some data and (.~) allows you to set some data
  • makeLenses is what does all the magic of creating your accessors
  • I haven’t found anywhere that specifically says this, but it seems that your fields in a record structure need to be preceded with an underscore

An Example

{-# LANGUAGE TemplateHaskell #-}

import Control.Lens

data Ball = Ball { _position :: (Double, Double), _velocity :: (Double, Double) }
	deriving (Show)

-- create the accessors for the Ball type
makeLenses ''Ball

-- | Animates a ball's position with respect to a timestep.
-- Takes a ball's existing position and velocity and animates it
-- by the time step provided
--
animate :: Ball -> Double -> Ball
animate b t = do
	position .~ (px + vx * t, py + vy * t) $ b
  where (px, py) = b ^. position
		(vx, vy) = b ^. velocity

main :: IO ()
main = do
	-- the original ball
	let b = Ball { _position = (4.5, 6.2), _velocity = (-0.3, 1.2) }
	-- animate the ball by 1 full timestep
	let b' = animate b 1

	putStrLn $ "Initial ball : " ++ (show b)
	putStrLn $ "Animated ball: " ++ (show b')