Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Writing Files - Ryan Mulligan
Las Vegas Ruby Group
May 21, 2014
0
27
Writing Files - Ryan Mulligan
Las Vegas Ruby Group
May 21, 2014
Tweet
Share
More Decks by Las Vegas Ruby Group
See All by Las Vegas Ruby Group
Ruby ISO Standard - David Grayson
lvrug
0
87
Windows Automation - Howard Feldman
lvrug
0
32
Separating Your Application from Rails - Brian Hughes
lvrug
0
64
SWIG and Ruby - David Grayson
lvrug
0
35
Practical Object-Oriented Design in Ruby - Charles Jackson
lvrug
3
91
The Hamster Gem - Ryan Mulligan
lvrug
1
64
Varnish+Redis - Russ Smith
lvrug
1
69
Lambdas and Pops - Jan Hettich
lvrug
0
32
Making Good Use of Fonts - Russ Smith
lvrug
1
38
Featured
See All Featured
Designing with Data
zakiwarfel
91
4.2k
How to name files
jennybc
47
73k
What's new in Ruby 2.0
geeforr
336
30k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
217
21k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
318
19k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
7
570
Mobile First: as difficult as doing things right
swwweet
213
7.8k
Documentation Writing (for coders)
carmenintech
51
2.9k
Code Review Best Practice
trishagee
50
11k
Side Projects
sachag
451
37k
Fantastic passwords and where to find them - at NoRuKo
philnash
31
1.8k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
44
14k
Transcript
writing files ryantm.com https://github.com/ryantm/lvrug_atomic
File.write('atomic1.txt', 'Hello world') atomic1.rb
strace (Linux) $ strace ruby atomic1.rb try dtruss on OS
X
$ strace ruby atomic1.rb …. open("atomic1.txt", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 7
fcntl(7, F_GETFD) = 0x1 (flags FD_CLOEXEC) fstat(7, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 ioctl(7, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fffcafe2b60) = -1 ENOTT Y (Inappropriate ioctl for device) write(7, "Hello world", 11) = 11 close(7) = 0 ...
between open and write reading might read nothing (truncated) writes
to file erased
File.open('atomic2.txt', 'w') do |f| 1111.times do f.write 'Hello world' end
end atomic2.rb
$ strace ruby atomic2.rb open("atomic2.txt", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 7 fcntl(7,
F_GETFD) = 0x1 (flags FD_CLOEXEC) fstat(7, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 ioctl(7, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fff12593520) = -1 ENOTT Y (Inappropriate ioctl for device) write(7, "Hello worldHello worldHello worl"..., 8184) = 8184 write(7, "Hello world", 11) = 11 write(7, "Hello worldHello worldHello worl"..., 4026) = 4026 close(7)
between write and write reader reads partial (corrupted?) data other
writers - truncation - interleaving
solutions use temporary files - simple use journaling - used
by most databases transactional file systems - NTFS has but deprecated - otherwise academic
require 'fileutils' File.write('temp.txt', 'hello world') FileUtils.mv('temp.txt', "atomic5.txt") atomic5.rb
$ strace ruby atomic5.rb open("temp.txt", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 7 …
write(7, "hello world", 11) = 11 close(7) = 0 stat("atomic5.txt", {st_mode=S_IFREG|0644, st_size=11, ...}) = 0 stat("temp.txt", {st_mode=S_IFREG|0644, st_size=11, ...}) = 0 stat("atomic5.txt", {st_mode=S_IFREG|0644, st_size=11, ...}) = 0 stat("temp.txt", {st_mode=S_IFREG|0644, st_size=11, ...}) = 0 stat("atomic5.txt", {st_mode=S_IFREG|0644, st_size=11, ...}) = 0 rename("temp.txt", "atomic5.txt") = 0
requirements no one read temp file only one writer of
temp file only one file updater (file write locking)
further research how a rollback journal works http://www.sqlite.org/atomiccommit.html
further research how a rollback journal works http://www.sqlite.org/atomiccommit.html references.txt in
https://github.com/ryantm/lvrug_atomic
questions ryantm.com https://github.com/ryantm/lvrug_atomic