diff options
author | Eric Wong <e@80x24.org> | 2015-09-18 01:37:53 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2015-09-18 21:23:53 +0000 |
commit | 761736a312a103ba522abac52a604564f9e788ce (patch) | |
tree | 283a952c417d4be4573e1e26a9b546e0b1fdadf6 /lib/PublicInbox/NewsGroup.pm | |
parent | 62ee3cb36dd08f17e444e96dc80108464ee10cba (diff) | |
download | public-inbox-761736a312a103ba522abac52a604564f9e788ce.tar.gz |
Implementing NEWNEWS, XHDR, XOVER efficiently will require additional caching on top of msgmap. This seems to work with lynx and slrnpull, haven't tried clients. DO NOT run in production, yet, denial-of-service vulnerabilities await!
Diffstat (limited to 'lib/PublicInbox/NewsGroup.pm')
-rw-r--r-- | lib/PublicInbox/NewsGroup.pm | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/PublicInbox/NewsGroup.pm b/lib/PublicInbox/NewsGroup.pm new file mode 100644 index 00000000..6cc3f248 --- /dev/null +++ b/lib/PublicInbox/NewsGroup.pm @@ -0,0 +1,81 @@ +# Copyright (C) 2015 all contributors <meta@public-inbox.org> +# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt) +package PublicInbox::NewsGroup; +use strict; +use warnings; +use fields qw(name git_dir address domain mm gcf search); +use Scalar::Util qw(weaken); +require Danga::Socket; +require PublicInbox::Msgmap; +require PublicInbox::GitCatFile; + +sub new { + my ($class, $name, $git_dir, $address) = @_; + my $self = fields::new($class); + $self->{name} = $name; + $self->{domain} = ($address =~ /\@(\S+)\z/) ? $1 : 'localhost'; + $self->{git_dir} = $git_dir; + $self->{address} = $address; + $self; +} + +sub defer_weaken { + my ($self, $field) = @_; + Danga::Socket->AddTimer(30, sub { weaken($self->{$field}) }); +} + +sub gcf { + my ($self) = @_; + $self->{gcf} ||= eval { + my $gcf = PublicInbox::GitCatFile->new($self->{git_dir}); + + # git repos may be repacked and old packs unlinked + defer_weaken($self, 'gcf'); + $gcf; + }; +} + +sub mm { + my ($self) = @_; + $self->{mm} ||= eval { + my $mm = PublicInbox::Msgmap->new($self->{git_dir}); + + # may be needed if we run low on handles + defer_weaken($self, 'mm'); + $mm; + }; +} + +sub search { + my ($self) = @_; + $self->{search} ||= eval { + require PublicInbox::Search; + my $search = PublicInbox::Search->new($self->{git_dir}); + + # may be needed if we run low on handles + defer_weaken($self, 'search'); + $search; + }; +} + +sub description { + my ($self) = @_; + open my $fh, '<', "$self->{git_dir}/description" or return ''; + my $desc = eval { local $/; <$fh> }; + chomp $desc; + $desc =~ s/\s+/ /smg; + $desc; +} + +sub update { + my ($self, $new) = @_; + $self->{address} = $new->{address}; + $self->{domain} = $new->{domain}; + if ($self->{git_dir} ne $new->{git_dir}) { + # new git_dir requires a new mm and gcf + $self->{mm} = $self->{gcf} = undef; + $self->{git_dir} = $new->{git_dir}; + } +} + +1; |