From 5b78246d11948e93f54ae32dd800e9adaf55a546 Mon Sep 17 00:00:00 2001
From: joey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Date: Mon, 13 Aug 2007 07:00:53 +0000
Subject: [PATCH] memoization for injected RPC functions is a very, very good
 thing

---
 IkiWiki/Plugin/external.pm      | 2 ++
 doc/plugins/write/external.mdwn | 6 +++++-
 plugins/externaldemo            | 5 +++--
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/IkiWiki/Plugin/external.pm b/IkiWiki/Plugin/external.pm
index e3504a30d..9c31a70eb 100644
--- a/IkiWiki/Plugin/external.pm
+++ b/IkiWiki/Plugin/external.pm
@@ -107,6 +107,7 @@ sub rpc_call ($$;@) { #{{{
 } #}}}
 
 package IkiWiki::RPC::XML;
+use Memoize;
 
 sub getvar ($$$) { #{{{
 	my $plugin=shift;
@@ -142,6 +143,7 @@ sub inject ($@) { #{{{
 		IkiWiki::Plugin::external::rpc_call($plugin, $params{call}, @_)
 	};
 	eval qq{*$params{name}=\$sub};
+	memoize($params{name}) if $params{memoize};
 	return 1;
 } #}}}
 
diff --git a/doc/plugins/write/external.mdwn b/doc/plugins/write/external.mdwn
index ca30dd229..3612dd9c3 100644
--- a/doc/plugins/write/external.mdwn
+++ b/doc/plugins/write/external.mdwn
@@ -78,6 +78,9 @@ example, make an RPC call to `inject`. Pass it named parameters "name" and
 "Ikiwiki::rcs_update" and "call" is the RPC call ikiwiki will make whenever
 that function is run.
 
+If the RPC call is memoizable, you can also pass a "memoize" parameter, set
+to 1.
+
 ## Limitations of XML RPC
 
 Since XML RPC can't pass around references to objects, it can't be used
@@ -112,7 +115,8 @@ number of calls.
 Injecting a replacement for a commonly called ikiwiki function
 could result in a lot more RPC calls than expected and slow
 eveything down. `pagetitle`, for instance, is called about 100 times
-per page build.
+per page build. Memoizing injected functions whenever possible is a very
+good idea.
 
 In general, use common sense, and your external plugin will probably
 perform ok.
diff --git a/plugins/externaldemo b/plugins/externaldemo
index 6bbced30e..1321a4bc5 100755
--- a/plugins/externaldemo
+++ b/plugins/externaldemo
@@ -102,8 +102,9 @@ sub import {
 
 	# Here's an example of how to inject an arbitrary function into
 	# ikiwiki. Ikiwiki will be able to call bob() just like any other
-	# function.
-	rpc_call("inject", name => "IkiWiki::bob", call => "bob");
+	# function. Note use of automatic memoization.
+	rpc_call("inject", name => "IkiWiki::bob", call => "bob",
+		memoize => 1);
 
 	# Here's an exmaple of how to access values in %IkiWiki::config.
 	print STDERR "url is set to: ".
-- 
2.39.5