about summary refs log tree commit homepage
path: root/lib/PublicInbox/NewsGroup.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2015-09-18 01:37:53 +0000
committerEric Wong <e@80x24.org>2015-09-18 21:23:53 +0000
commit761736a312a103ba522abac52a604564f9e788ce (patch)
tree283a952c417d4be4573e1e26a9b546e0b1fdadf6 /lib/PublicInbox/NewsGroup.pm
parent62ee3cb36dd08f17e444e96dc80108464ee10cba (diff)
downloadpublic-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.pm81
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;