This doesn’t seem to be terribly well documented, so for future reference:
F = fun() -> mnesia:select(Tab,[{'_',[],['$_']}]) end,
mnesia:activity(transaction, F).
This doesn’t seem to be terribly well documented, so for future reference:
F = fun() -> mnesia:select(Tab,[{'_',[],['$_']}]) end,
mnesia:activity(transaction, F).
If you’re trying to run Meteor in a Vagrant VirtualBox, and getting an error like this when starting the local server:
vagrant@precise32:/vagrant$ meteor [[[[[ /vagrant ]]]]] Unexpected mongo exit code 100. Restarting. Unexpected mongo exit code 100. Restarting. Unexpected mongo exit code 100. Restarting. Can't start mongod MongoDB had an unspecified uncaught exception. This can be caused by MongoDB being unable to write to a local database. Check that you have permissions to write to .meteor/local. MongoDB does not support filesystems like NFS that do not allow file locking.
As the error message suggests, the problem is caused by the way Vagrant is sharing the src folder with the VM. The easiest solution (suggested here) is to move the Mongo DB data folder to somewhere on the VM, with a symlink in the Meteor folder:
vagrant@precise32:/vagrant/.meteor/local$ ln -s ~/db/ vagrant@precise32:/vagrant/.meteor/local$ ls -la total 12 drwxr-xr-x 1 vagrant vagrant 4096 Jun 17 2013 . drwxr-xr-x 1 vagrant vagrant 4096 Jun 17 21:47 .. lrwxrwxrwx 1 vagrant vagrant 17 Jun 17 2013 db -> /home/vagrant/db/
And you should be back in business!
vagrant@precise32:/vagrant$ meteor [[[[[ /vagrant ]]]]] => Meteor server running on: http://localhost:3000/
UPDATE: this won’t work on a Windows host, apparently; due to the lack of support for symlinks. Sorry!
I’ve recently been getting to know WPF rather better than I’d like.
We make a lot of use of the Prism DelegateCommand. One such command had a handler attached to it’s CanExecuteChanged event:
var command = new DelegateCommand(Execute, CanExecute); command.CanExecuteChanged += OnCommandCanExecuteChanged;
When we asked the command to re-evaluate whether it could execute:
command.RaiseCanExecuteChanged();
Then OnCommandCanExecuteChanged should have been called.
Sometimes it was, sometimes it wasn’t. Or, more accurately, it was at first and then later it wasn’t.
A bit of digging into the sauce of the DelegateCommand (thanks R#!), confirmed the suspicion:
public event EventHandler CanExecuteChanged
{
add
{
WeakEventHandlerManager.AddWeakReferenceHandler(ref this._canExecuteChangedHandlers, value, 2);
}
remove
{
WeakEventHandlerManager.RemoveWeakReferenceHandler(this._canExecuteChangedHandlers, value);
}
}
The command holds a weak reference to the event handler. And, if that’s the only reference, then it’s just a matter of time before it gets GCed; and your handler will no longer be called.
After some hair pulling, and a few false starts, it turned out the solution was to keep our own reference to the actual event handler. Makes perfect sense now, but it certainly wasn’t obvious at first!
public class CommandHolder
{
private readonly EventHandler eventHandler;
public ICommand Command { get; private set; }
public CommandHolder()
{
Command = new DelegateCommand(Execute, CanExecute);
eventHandler = OnCanExecuteChanged;
Command.CanExecuteChanged += eventHandler;
}
private void Execute() { }
private bool CanExecute() { return true; }
private void OnCanExecuteChanged(object sender, EventArgs e) { }
}
I assume the reason for the weak references is to try & avoid memory leaks caused by failing to unbind event handlers. Unfortunately, it can leave you with a tricky bug to investigate.
I mainly run Windows VMs on a Linux host. When you update to the latest version of VirtualBox, it’s best to update (or install) the guest additions.
Normally, you can run the installer by selecting Devices->Install Guest Additions from the VirtualBox menu. This doesn’t always seem to work though, so it’s necessary to run the installer manually.
On a Linux host, the guest additions can be found in /usr/share/virtualbox/VBoxGuestAdditions.iso. If you share this folder with the guest, you can mount the ISO directly using various free tools. However I find it easier to just copy it to the guest, use 7-zip to extract everything, and run VBoxWindowsAdditions.exe.
I have a webmachine app that uses Mnesia as an in-memory DB. To begin with, I was just calling mnesia:start() in the erlang terminal provided after running start.sh. But, after forgetting to start it a couple of times, I looked for a better solution.
My first stop, the internet, didn’t provide me with any answers (either it should be obvious, or I was using the wrong keywords!). So I decided to try adding it to the dependency list in my application resource file (.app.src).
{application, restbucks,
[
{description, "restbucks"},
{vsn, "1"},
{modules, []},
{registered, []},
{applications, [
kernel,
... snip ...
webmachine,
mnesia
]},
{mod, { restbucks_app, []}},
{env, []}
]}.
Unfortunately, that didn’t seem to have any effect whatsoever.
Luckily, I’d discovered through my adventures with eunit, that erl can take a number of arguments (-s) that will be executed when starting. So I modified my start.sh script appropriately:
exec erl -pa $PWD/ebin $PWD/deps/*/ebin -boot start_sasl -s mnesia start -s reloader -s restbucks
Whether this is a good idea remains to be seen, but it seems to work!
Following on from the fun of giving write permissions on a folder to a user, today’s installment covers adding a domain user to a local group.
Specifically, the group “Performance Log Users”, which allows a process to use (rather than create) perf counters.
function Add-UserToPerformanceLogUsersGroup($user, $session) {
Invoke-Command -Args $user -Session $session -ErrorAction Stop -ScriptBlock {
param($user)
$groupName = "Performance Log Users"
$group = [ADSI]("WinNT://$env:COMPUTERNAME/$groupName,group")
# check if user is already a member
$members = @($group.psbase.Invoke("Members"))
$matches = $members | where { $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) -eq $user.split("\")[1] }
if ($matches -eq $null) {
Write-Host "Adding $user to $groupName group"
$user = $user.replace("\", "/")
$group.add("WinNT://$user,user")
}
}
}
Caveat: the user specified is assumed to be a fully qualified DOMAIN\User, hence the unpleasant string manipulation.
I have a lot of love for TeamCity, and one of the many things that makes it easy to get a build configuration up and running is its concept of “build steps“.
Recently, however, I’ve started to worry about our use (or abuse) of them. My main concern is the fact that it can make it very hard to reproduce a failing build (works on my machine!).
There’s always going to be some differences between the build running on the CI server, and my local build (hardware, installed software, timing, etc). But I’d like to reduce them to the bare minimum. It’s bad enough that I’m running a sh*tty laptop with XP, while the build agent is on 64 bit Server 2008, without having a completely different build process.
I was never a fan of MSBuild, but at least having a build script in with the sauce meant that you could run a local build before checking in.
Some of our build configs now have up to 8 build steps (StyleCop, NuGet install & update, build, test, source index, NuGet pack & publish, etc), any of which could cause a build to fail without being easily reproduced locally. Which encourages people to just check in, and hope for the best. And the slow feedback cycle when trying to fix an issue is a real gumption trap.
So, what’s the alternative? I couldn’t face going back to an xml based build tool (e.g. NAnt or MSBuild), but a scripting language like Ruby (Rake) or Powershell is ideal. In our case, I’d like to replace the steps with a build.ps1 (and some shared modules for common tasks).
As part of our deployment process, we need to give an IIS app pool identity write permissions on a log folder.
There are a few articles describing how to set permissions using powershell, but getting the incantation exactly right was a bit tricky.
So, for future reference, here it is:
function Set-RightsForAppPoolOnLogFolder($appPoolName, $session) {
Write-Host "Setting app pool identity write rights on log folder"
Invoke-Command -Args $appPool -Session $session -ErrorAction Stop -ScriptBlock {
param($appPoolName)
$logFolder = "D:\Logs"
$acl = Get-Acl $logFolder
$identity = "IIS AppPool\$appPoolName"
$fileSystemRights = "Write"
$inheritanceFlags = "ContainerInherit, ObjectInherit"
$propagationFlags = "None"
$accessControlType = "Allow"
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($identity, $fileSystemRights, $inheritanceFlags, $propagationFlags, $accessControlType)
$acl.SetAccessRule($rule)
Set-Acl $logFolder $acl
}
}
We use the NuGet package restore functionality as part of our build. None of the packages are under source control, they are downloaded (from an internal subset of the public feed) before compilation.
Unfortunately, there is a slight shortcoming in some older versions of NuGet that results in far more requests being made than are strictly necessary. This was fixed in version 2.0, but that won’t be supported in TeamCity until 7.1 is released (currently EAP only).
For now, you can choose “custom” as your NuGet version:
and provide the path to NuGet.exe.
We saw a drastic improvement in build times (from 15-20 mins, down to under 5).
We use TeamCity (7.0.3) both as a CI server, and a private NuGet feed. I have a lot of love for TC, but I currently have one major concern:
If my tests fail, TC still publishes the NuGet packages.
Not cool.
I raised this is an issue with JetBrains, and was told it was a feature request. And, that as a workaround, I could split my builds in two and separate the publish step from the rest of the build.
As far as I’m concerned, this is a showstopper bug. It introduces broken behaviour out of the box, which you won’t find out about until you realise a broken package is in use downstream. If JetBrains expects people to use TeamCity as a NuGet feed, this needs to be fixed.
(There’s also no (easy) way to remove packages from the feed, but I’m less concerned about that :) )