nsmcp::FileLogSource method read (public)

 <instance of nsmcp::FileLogSource[i]> read

Defined in /usr/local/ns/tcl/nsmcp/lib/log-source.tcl

Testcases:
No testcase defined.
Source code:
ns_mutex lock ${:mutex}
try {
    file stat ${:path} before
    set channel [open ${:path} rb]
    try {
        fconfigure $channel -translation binary -encoding binary
        file stat ${:path} opened
        if {[list $before(dev) $before(ino)] ne [list $opened(dev) $opened(ino)]} {
            error "log file changed while opening; retry"
        }
        set identity [list $before(dev) $before(ino)]
        set reset false
        set generation 1
        if {[nsv_exists ${:store} ${:cacheKey}] && [nsv_get ${:store} ${:cacheKey} state]} {
            set generation [dict get $state generation]
            set prefix [dict get $state prefix]
            # A fixed prefix also detects common copytruncate-and-regrow
            # cases that have already grown beyond the saved cursor.
            set prefixNow [read $channel [string length $prefix]]
            if {$identity ne [dict get $state identity] ||
                $before(size) < [dict get $state cursor] || $prefixNow ne $prefix} {
                set reset true
                incr generation
            }
        } else {
            set reset true
        }
        if {$reset} {
            seek $channel 0
            set prefix [read $channel [expr {min(256, $before(size))}]]
            set state [:emptyState $identity $generation $prefix]
        }
        if {[dict get $state prefix] eq "" && $before(size) > 0} {
            seek $channel 0
            dict set state prefix [read $channel [expr {min(256, $before(size))}]]
        }
        seek $channel [dict get $state cursor]
        # Read only bytes visible at the snapshot, within the work budget.
        set count [expr {min(${:maxReadBytes}, max(0, $before(size)-[dict get $state cursor]))}]
        set state [:consume $state [read $channel $count]]
        file stat ${:path} after
        seek $channel 0
        set prefix [dict get $state prefix]
        set prefixAfter [read $channel [string length $prefix]]
        if {[list $after(dev) $after(ino)] ne $identity ||
            $after(size) < $before(size) || $prefixAfter ne $prefix} {
            # Do not publish a mixed snapshot if rotation races this read.
            error "log file changed during read; retry"
        }
        nsv_set ${:store} ${:cacheKey} $state
        set events [dict get $state events]
        if {[dict get $state pending] ne ""} {lappend events [dict get $state pending]}
        set events [lrange $events end-[expr {${:maxEvents}-1}] end]
        return [dict create generation $generation reset $reset  cursor [dict get $state cursor]  backlogBytes [expr {max(0, $before(size)-[dict get $state cursor])}]  partialLineBytes [expr {[dict get $state cursor]-[dict get $state fragmentOffset]}]  events $events]
    } finally {close $channel}
} finally {ns_mutex unlock ${:mutex}}
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: