-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change DigestIO digest on read or write flags for exclusive mode enum
- Loading branch information
1 parent
3c67b5a
commit 5bda0ef
Showing
7 changed files
with
227 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require "logger" | ||
|
||
module Migrate::Logging | ||
@@logger : Logger = Logger.new(STDOUT).tap do |l| | ||
l.formatter = Logger::Formatter.new do |severity, datetime, progname, message, io| | ||
io << severity[0] << ", [" << datetime << " #" << Process.pid << "] " | ||
io << severity.rjust(5) << " -- " << progname << ": " << message | ||
io << "My additional suff" | ||
end | ||
end | ||
|
||
def logger | ||
@@logger | ||
end | ||
|
||
def self.logger | ||
@@logger | ||
end | ||
end | ||
|
||
class Foo | ||
include Migrate::Logging | ||
def foo | ||
logger.warn("Hello!") | ||
42 | ||
end | ||
end | ||
|
||
Foo.new.foo | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# puts "A" | ||
# spawn do | ||
# puts "B" | ||
# end | ||
# puts "C" |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
module IO | ||
def self.deferred(&block : IO -> Void) | ||
IO::Deferred.new(block).reader | ||
end | ||
end | ||
|
||
class IO::Deferred | ||
include IO | ||
|
||
@target : Bytes? | ||
@raw : Bytes | ||
@buffer : Bytes | ||
|
||
@chan_reader : Channel(Int32) | ||
@chan_writer : Channel(Int32) | ||
@chan_block : Channel(Nil) | ||
|
||
@started : Bool | ||
@finished : Bool | ||
|
||
@reader : Reader? | ||
@writer : Writer? | ||
|
||
def initialize(@block : IO -> Void) | ||
@raw = Bytes.new(4096) | ||
@buffer = Bytes.new(@raw.to_unsafe, 0) | ||
@chan_reader = Channel(Int32).new | ||
@chan_writer = Channel(Int32).new | ||
@chan_block = Channel(Nil).new | ||
@started = false | ||
@finished = false | ||
end | ||
|
||
def read(target : Bytes) | ||
puts "READING 1" | ||
|
||
try_start | ||
written = 0 | ||
|
||
puts "READING 2" | ||
|
||
# Store the requested target buffer to be written in the `write` method | ||
@target = target | ||
|
||
# Grab what's leftover in the buffer, if any | ||
if @buffer.size > 0 | ||
writeable_size = [@buffer.size, target.size].min | ||
target.copy_from(@buffer.to_unsafe, writeable_size) | ||
@buffer += writeable_size | ||
target += writeable_size | ||
written += writeable_size | ||
end | ||
|
||
# Unblock the writing fiber only if the buffer did not cover the read request, | ||
# and block until the write method signals us that the write was completed | ||
while target.size > 0 && !@finished | ||
@chan_writer.send(target.size) | ||
select | ||
when bytes = @chan_reader.receive | ||
written += bytes | ||
when @chan_block.receive | ||
@finished = true | ||
end | ||
end | ||
|
||
@target = nil | ||
return written | ||
end | ||
|
||
def write(source : Bytes) | ||
# Block until the main reader fiber signals us for a write request | ||
requested = @chan_writer.receive | ||
|
||
# Write to the target slice | ||
target = @target.not_nil! | ||
writeable_size = [target.size, source.size].min | ||
target.copy_from(source.to_unsafe, writeable_size) | ||
source += writeable_size | ||
|
||
# Store leftover (if any) in buffer, resizing underlying raw buffer if needed | ||
if source.size > 0 | ||
@raw = Bytes.new(source.size) if source.size > @raw.size | ||
@raw.copy_from(source.to_unsafe, source.size) | ||
end | ||
|
||
# Update buffer view of raw underlying buffer | ||
@buffer = Bytes.new(@raw.to_unsafe, source.size) | ||
|
||
# Signal the reader fiber that this write operation is finished, | ||
# sending the number of bytes written to target | ||
@chan_reader.send(writeable_size) | ||
|
||
return nil | ||
end | ||
|
||
def reader | ||
@reader ||= Reader.new(self) | ||
puts "Yielding reader" | ||
@reader.not_nil! | ||
end | ||
|
||
def writer | ||
@writer ||= Writer.new(self) | ||
puts "Yielding writer" | ||
@writer.not_nil! | ||
end | ||
|
||
def try_start | ||
unless @started | ||
@started = true | ||
spawn do | ||
@block.call(writer) | ||
@chan_block.send(nil) | ||
end | ||
end | ||
end | ||
end | ||
|
||
class IO::Deferred::Reader | ||
include IO | ||
|
||
def initialize(@io : IO::Deferred) | ||
end | ||
|
||
def read(slice : Bytes) | ||
@io.read(slice) | ||
end | ||
|
||
def write(slice : Bytes) | ||
raise IO::Error.new("can't write to IO::Deferred::Reader") | ||
end | ||
end | ||
|
||
class IO::Deferred::Writer | ||
include IO | ||
|
||
def initialize(@io : IO::Deferred) | ||
end | ||
|
||
def read(slice : Bytes) | ||
raise IO::Error.new("can't read from IO::Deferred::Writer") | ||
end | ||
|
||
def write(slice : Bytes) | ||
@io.write(slice) | ||
end | ||
end | ||
|
||
puts "Before Starting" | ||
|
||
reader = IO.deferred do |writer| | ||
puts "BLOCK | Initialising writer" | ||
4.times do | ||
puts "BLOCK | Writing 6 bytes" | ||
writer.write("foobar".to_slice) | ||
end | ||
end | ||
|
||
puts "Starting" | ||
# puts reader.read_string(6) | ||
# puts "1" | ||
# puts reader.read_string(6) | ||
# puts "2" | ||
# puts reader.read_string(6) | ||
# puts "3" | ||
# puts reader.read_string(6) | ||
# puts "4" | ||
# puts reader.read_string(6) | ||
# puts "5" | ||
# puts reader.read_string(6) | ||
# puts "6" | ||
# # puts reader.read_string(1) | ||
# # puts reader.read_string(1) | ||
# # puts reader.read_string(16) | ||
# # puts reader.gets_to_end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters