I was just coding up something Eclipse for work and decided I wanted to pop a dialog to ask the user "Do you want to save?" I did a quick Google search to see if I could find the name of dialog I wanted - and instead, ran across this blog post. The author, in a nutshell, through the post and his subsequent comments, argues that asking the user to save is a bad thing and, instead, your program should always be saving - but in such a way that it is possible to roll back the changes.
At first blush, that seems like a really good idea. If the program is always saving, you never need to worry about losing your work, so you never need to stop and think "now I want to save" - and hence can't forget to do it. Likewise, if you discover that you've been going down the wrong path, you can always step back and reverse your changes (just undo until you get back to where you would have preferred to be). Presumably, the program will even reload your undo history when you reload a given document.
Here's the problem. "Save" does more than just commit a set of recent changes to non-volatile storage. It's also an expression of intent that means "and now I've made a meaningful set of changes to which I want to be able to return (in the event of a crash, etc.)." In some circumstances, these two things are equivalent (or very nearly so). For instance, when I'm typing a blog, I might periodically be saving my entry because, after all, any change I've made is meaningful. Sure, I might decide later to back up, but there's no problem if basically every change I make is saved.
This is simply not true in all circumstances. Imagine, instead, a database application with hundreds (or thousands or millions) of users, all of whom are working on pieces of a single, centralized data store. Anne opens a form to edit an entry in one of the records on the database. As she makes changes, she effectively breaks things - while updating field 1 but not having had a chance to update fields 2 and 3, the entry is now in an inconsistent state: its data no longer makes sense and should not - or cannot - be committed back to the database. If it were committed (if the database allowed it), Bob might see some of Anne's changes but not all of them and he might either be thoroughly confused, or take some incorrect action based on the inconsistent data.
Save, then, becomes the mechanism by which Anne says "And now my data is consistent and should be visible to all users of this database." Likewise, should Anne try to close the form through which she is editing the entry, the software well and truly should ask her "are you sure you don't want to save those changes?" Here, save is a clear expression of intent and cannot be serviced with auto save plus versioning.
One final thought: it's tempting to say that the software should ensure that Anne cannot make changes to any entry and in so doing put that entry in an inconsistent state - even temporarily. But that assumes that there is some mechanism by which the software can "guess" at reasonable or correct values for all related fields when any one of them is changed. In the case of a set of related dates (Earliest Launch Time, Latest Launch Time, Preferred Launch Time), this is easily handled. In general, simple solutions cannot be found: when updating code, for instance, how is the software supposed to guess at a correct set of actions to take in response to an arbitrary line being updated? Anne must make the changes she had in mind and then signal to the software that now her changes should be committed and thus should be visible to all users.
Showing posts with label arcana. Show all posts
Showing posts with label arcana. Show all posts
Monday, October 27, 2008
Tuesday, November 20, 2007
Java 1.6 for OS X
There are hundreds of thousands of pages on the 'Net right now by angry people who want to see Apple put Java 1.6 back into Leopard. I'm one of them. But rather than waste bandwidth rehashing the issues, I'll simply register my complaint: without Java 1.6 on the Mac, I can't use the Mac for Java development for projects I have going on at work. It's that simple and it's totally unacceptable. Way to go Apple: congrats on pissing off hundreds of thousands of loyal customers. Great marketing decision - especially in refusing to make an official statement regarding Java 1.6.
Here's making my voice heard: 13949712720901forosx
Here's making my voice heard: 13949712720901forosx
Wednesday, April 25, 2007
Avoiding VPNs with SSH and Curl
All of the VPN clients I've used have an annoying habit of rebuilding my routing tables so that all traffic passes through the VPN, as opposed to target-network-specific traffic (by which I mean traffic destined for the network to which I've established the VPN connection). This can of course be fixed by manually rebuilding routing tables after the VPN connection is established: the default route (through the VPN) is reset to the gateway previously serving default traffic; usually, VPN clients add a specific route for the target network anyway, so no further change is needed.
But there is a good reason VPN clients route all traffic through the VPN. Frequently, the target network has permissions to access stuff out on the web that your host network might not. For instance, universities and libraries often maintain IP-pool-based subscriptions to online digital libraries. So, sitting on the university network, you can access material on the ACM or IEEE website; at home, you cannot. Since all traffic goes through the VPN, when you have established a connection to the university, you can access those materials.
Of course, that slows down all of your Internet browsing, since all requests and replies must pass through the VPN. Futhermore, it means that all of your data is passing through the target network - something you may not want, for privacy reasons. Hence the routing-table fix mentioned above.
So here's a way to get around all that. It assumes you have an account on machine in the target network, that said machine is accessible from the Internet, and that said machine runs SSH and has curl installed. Similarly to using SSH to move things, you can use SSH to fetch Internet resources that from within the target network, sans VPN.
Not only does this let you grab things as if you were within the target network avoiding the time-consuming VPN connect/disconnect, it does so without placing any temporary files on the remote machine "host." And, since curl prints its status information to STDERR, you get to see your download's progress, even as curl saves the file to your local disk.
But there is a good reason VPN clients route all traffic through the VPN. Frequently, the target network has permissions to access stuff out on the web that your host network might not. For instance, universities and libraries often maintain IP-pool-based subscriptions to online digital libraries. So, sitting on the university network, you can access material on the ACM or IEEE website; at home, you cannot. Since all traffic goes through the VPN, when you have established a connection to the university, you can access those materials.
Of course, that slows down all of your Internet browsing, since all requests and replies must pass through the VPN. Futhermore, it means that all of your data is passing through the target network - something you may not want, for privacy reasons. Hence the routing-table fix mentioned above.
So here's a way to get around all that. It assumes you have an account on machine in the target network, that said machine is accessible from the Internet, and that said machine runs SSH and has curl installed. Similarly to using SSH to move things, you can use SSH to fetch Internet resources that from within the target network, sans VPN.
ssh -l name host "curl address" > local_filewill do the trick. "name" is your account name on the machine "host," and "address" is the URL of the resource you want to access from within the target network; "local_file" is the name of the file on your local machine in which the fetched resource will be saved.
Not only does this let you grab things as if you were within the target network avoiding the time-consuming VPN connect/disconnect, it does so without placing any temporary files on the remote machine "host." And, since curl prints its status information to STDERR, you get to see your download's progress, even as curl saves the file to your local disk.
Tuesday, April 10, 2007
Wedged Repositories
I administer a Fedora Core 6 machine at work. Logged in today and told it to update itself ("yum update"). Checked back a few minutes ago and discovered that yum hadn't made any progress. So I killed off yum, poked around, and discovered that cron had spawned countless instances of this funny rpmq process - one of which was running at 100% on a CPU (I have cores in that machine) and had been running for - well - a long time. Like days. So I killed all of them off, and tried yum again. Still no luck.
Poking around, I found a post on the 'Net that suggested the right thing to do was to delete all of the "__db.00*" files sitting under /var/lib/rpm. That did the trick - unwedged the repository that rpm and yum manage - but I've still no idea why rpmq started dying by falling into an infinite loop. Will have to keep my eyes on that machine for a bit.
Have I ever mentioned my lack of fondness for computers? Yeah. It's a love-hate relationship. On most platforms, it gravitates more to hate than love.
Poking around, I found a post on the 'Net that suggested the right thing to do was to delete all of the "__db.00*" files sitting under /var/lib/rpm. That did the trick - unwedged the repository that rpm and yum manage - but I've still no idea why rpmq started dying by falling into an infinite loop. Will have to keep my eyes on that machine for a bit.
Have I ever mentioned my lack of fondness for computers? Yeah. It's a love-hate relationship. On most platforms, it gravitates more to hate than love.
Names Are Like Titles
A good name is everything. Well, alright, not quite everything. But they sure are a lot.
For instance: in digital systems, there is a failure condition known as the Byzantine Generals Problem. (Rather than explaining it in any detail, I'll trust you to look it up on Wikipedia.) It turns out that it is a real problem, it really does happen in real systems, and the consequences of ignoring these types of failures can be quite severe. But it's got the dumbest name. Not because the name doesn't adequately describe the fault scenario - it does. No, because when you try to talk to a manager about it, it's instant confusion. "Wait a minute, here.... Treacherous lieutenants? How can computer components lie? This must be nonsense!" And so on. "Asymmetric faulty" is a much better term (though less cool sounding): it captures the essence of what happens and doesn't require you to imagine that computers are actively trying to be mischevious (or treacherous). I blame L. Lamport for it, since he first described the situation (with others) in this paper.
Here's another one for you. Ribbit. Go ahead. Guess what that is (before clicking on the link!). Give up? It's an add-in to Word and PowerPoint that allows you to enter equations in LaTeX syntax. Imagine trying to get your company to front the money for this tool.
Yeah. That'd go over real well. And while I'm griping, "LaTeX" isn't such a hot name, either. "Oh - that rubbery stuff?" Yeah. Another Lamport invention, I might add. Oh yeah - and Ribbit's tagline is "Even better than the real thing." Whatever that means.
I should not leave you with the impression that I am the King of Names, however. I'm rotten at coming up with good names - just as I'm rotten at coming up with good titles. But knowing that, I'd for sure get some advice before trying to market my next great product, theoretical contribution, etc. And I understand why people pay so much money for good marketing.
For instance: in digital systems, there is a failure condition known as the Byzantine Generals Problem. (Rather than explaining it in any detail, I'll trust you to look it up on Wikipedia.) It turns out that it is a real problem, it really does happen in real systems, and the consequences of ignoring these types of failures can be quite severe. But it's got the dumbest name. Not because the name doesn't adequately describe the fault scenario - it does. No, because when you try to talk to a manager about it, it's instant confusion. "Wait a minute, here.... Treacherous lieutenants? How can computer components lie? This must be nonsense!" And so on. "Asymmetric faulty" is a much better term (though less cool sounding): it captures the essence of what happens and doesn't require you to imagine that computers are actively trying to be mischevious (or treacherous). I blame L. Lamport for it, since he first described the situation (with others) in this paper.
Here's another one for you. Ribbit. Go ahead. Guess what that is (before clicking on the link!). Give up? It's an add-in to Word and PowerPoint that allows you to enter equations in LaTeX syntax. Imagine trying to get your company to front the money for this tool.
"Hey boss, I'd like you to buy a new tool and suggest that other members in the company give it a try."
"Really? What's it called?"
"Ribbit."
"...."
Yeah. That'd go over real well. And while I'm griping, "LaTeX" isn't such a hot name, either. "Oh - that rubbery stuff?" Yeah. Another Lamport invention, I might add. Oh yeah - and Ribbit's tagline is "Even better than the real thing." Whatever that means.
I should not leave you with the impression that I am the King of Names, however. I'm rotten at coming up with good names - just as I'm rotten at coming up with good titles. But knowing that, I'd for sure get some advice before trying to market my next great product, theoretical contribution, etc. And I understand why people pay so much money for good marketing.
Friday, April 6, 2007
Using SSH to Move Things
It comes up every once in a while that you want to make a tarball of something but can't, because the machine hosting the files you want to tar doesn't have enough space. Or, you want to copy some big mess of files across the network, but want to transmit them compressed, to speed up the transfer, without having to first tar and compress them, then copy them, and then uncompress them, and then remember to delete the tarball on the source machine.
In either case - and in other cases - it's ideal to be able to accomplish the migration in swell foop (fell swoop). SSH comes to the rescue. The command:
It works because you can give SSH a command after specifying the host IP, and SSH will login, execute the command, and logout when it's done. Any output to STDOUT or STDERR will be routed to the machine making the call to SSH, so you can pipe or redirect that output just as you would had the remote command originated on the local machine.
So in the above command, we use ssh to log into machine ''ip'' with username ''name'' and ask tar to create an archive of ''path'', sending output to STDOUT. The "[j|z]" bit will allow you to simultaneously bzip2 (j) or gzip (z) the tarball, as it is created, before it appears on STDOUT. On the other side of the pipe, we ask tar to expand the input it reads from STDIN; if we have used "j" or "z", we need to give it to tar here, too.
This is particularly elegant if the account on the remote (source) machine has an authorized key for the account on the local (destination) machine. In that case, you don't have to enter a password or do anything other than issue the command.
You can move all sorts of things this way, not just tarballs. Any program that can write its output to STDOUT and read input from STDIN can be used this way. I've used a similar incantation to move Subversion repositories from one machine to another and even to block-by-block copy the low-level contents of one hard disk to another, across the network.
In either case - and in other cases - it's ideal to be able to accomplish the migration in swell foop (fell swoop). SSH comes to the rescue. The command:
ssh -lwill do the trick nicely.tar c[j|z]O | tar x[j|z]
It works because you can give SSH a command after specifying the host IP, and SSH will login, execute the command, and logout when it's done. Any output to STDOUT or STDERR will be routed to the machine making the call to SSH, so you can pipe or redirect that output just as you would had the remote command originated on the local machine.
So in the above command, we use ssh to log into machine ''ip'' with username ''name'' and ask tar to create an archive of ''path'', sending output to STDOUT. The "[j|z]" bit will allow you to simultaneously bzip2 (j) or gzip (z) the tarball, as it is created, before it appears on STDOUT. On the other side of the pipe, we ask tar to expand the input it reads from STDIN; if we have used "j" or "z", we need to give it to tar here, too.
This is particularly elegant if the account on the remote (source) machine has an authorized key for the account on the local (destination) machine. In that case, you don't have to enter a password or do anything other than issue the command.
You can move all sorts of things this way, not just tarballs. Any program that can write its output to STDOUT and read input from STDIN can be used this way. I've used a similar incantation to move Subversion repositories from one machine to another and even to block-by-block copy the low-level contents of one hard disk to another, across the network.
Protecting Grep
So here's some real Arcana for you. This comes from the UNIX family of spells - some of the most-difficult-to-master magic out there.
Grep seems to need protection when it's used to process directory information, as in:
Who knows why grep needs it. Took me quite a while to figure out the solution to the problem, too. Which has resulted in a new bit of core UNIX lore, for me: when in doubt, blow away your environment with env prior to issuing your command.
Grep seems to need protection when it's used to process directory information, as in:
ls /some/path | grep -e [some pattern]This code may work differently if "/some/path" is a full path to the folder rather than ".". Issuing
env -i ls /some/path | grep -e [some pattern]appears to solve the problem.
Who knows why grep needs it. Took me quite a while to figure out the solution to the problem, too. Which has resulted in a new bit of core UNIX lore, for me: when in doubt, blow away your environment with env prior to issuing your command.
Subscribe to:
Posts (Atom)
