/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* $Rev$ $Date$ */ /** * A data cache component implementation which coordinates access to two * levels of backend read/write caches or stores. Each cache or store is * accessed through two references: a writer reference and a reader reference. * * This is useful if your level2 store is made of a master and slave * replicated databases, you can then wire the writer reference to the master * database and the reader reference to one your slave databases (assuming * that the updates eventually get replicated to the slave database, in the * meantime the updates will be retrieved from the level1 cache). */ #define WANT_HTTPD_LOG 1 #include "string.hpp" #include "function.hpp" #include "list.hpp" #include "value.hpp" #include "monad.hpp" namespace tuscany { namespace datacache { /** * Get an item from the cache. */ const failable get(const value& key, const lvvlambda& rcache1, const lvvlambda& wcache1, const lvvlambda& rcache2, unused const lvvlambda& wcache2) { // Lookup level1 cache const value val1 = rcache1(mklist("get", key)); if (!isNil(val1)) return val1; // Lookup level2 cache const value val2 = rcache2(mklist("get", key)); if (isNil(val2)) { ostringstream os; os << "Couldn't get cache entry: " << key; return mkfailure(str(os), 404, false); } // Update level1 cache wcache1(mklist("put", key, val2)); return val2; } /** * Post an item to the cache. */ const failable post(const value& key, const value& val, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) { const value id = append(key, mklist(mkuuid())); // Update level1 cache wcache1(mklist("put", id, val)); // Update level2 cache wcache2(mklist("put", id, val)); return id; } /** * Put an item into the cache. */ const failable put(const value& key, const value& val, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) { // Update level1 cache wcache1(mklist("put", key, val)); // Update level2 cache wcache2(mklist("put", key, val)); return trueValue; } /** * Patch an item in the cache. */ const failable patch(const value& key, const value& val, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) { // Update level1 cache wcache1(mklist("patch", key, val)); // Update level2 cache wcache2(mklist("patch", key, val)); return trueValue; } /** * Delete an item from the cache. */ const failable del(const value& key, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) { // Delete from level1 cache wcache1(mklist("delete", key)); // Delete from level2 cache wcache2(mklist("delete", key)); return trueValue; } } } extern "C" { const tuscany::value apply(const tuscany::list& params) { const tuscany::value func(car(params)); if (func == "get") return tuscany::datacache::get(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params)); if (func == "post") return tuscany::datacache::post(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params)); if (func == "put") return tuscany::datacache::put(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params)); if (func == "patch") return tuscany::datacache::patch(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params)); if (func == "delete") return tuscany::datacache::del(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params)); return tuscany::mkfailure(); } }