biff

A web framework + self-hosted deployment solution for Clojure. Repo: https://github.com/jacobobryant/biff. Docs: https://biff.findka.com
sandbags 2020-07-22T22:41:22.034600Z

I am interested in whether Biff might fit my use-case. I am building a Tuple Spaces service. If you’re not familiar essentially a tuple is an ordered list of values (e.g. [1 2 3 4] or [42 “What is six times seven?”]) and a tuple space supports operations such as out(…) to place a tuple into the space, read/take( template ) to get tuples where the template defines rules about what can appear in each position of the tuple. At the moment I have implemented a space using next.jdbc/honey SQL. While it works it’s not a very natural fit as and I am making use of joins in a way that I think is problematic. Now I am thinking about how to expose the service and maybe HTTP isn’t a great fit since tuple operations can block waiting for a matching tuple. I just came across Biff and I’m wondering if it plausibly sounds a good fit for this kind of problem?

2020-07-22T23:32:30.040100Z

It sounds like this would be an API for other services/apps to consume, i.e. it wouldn't be a user-facing app itself, is that correct? A lot of Biff's features (e.g. query subscriptions, authentication, authorization) are specifically for dealing with users and might not be needed. But it does sound like Crux could be a good fit, with web sockets instead of http for communication. So actually, if you did want to experiment at least with Crux + websockets, Biff does have those set up for you. You could use the example app as a template to get started, and then decide what parts you want to keep (if you just want Crux + websockets, might be easiest to copy and paste the relevant bits from Biff's source).

sandbags 2020-07-23T08:17:48.040900Z

It is offering a space as an API for other apps/services to consume. However there are wrinkles.

sandbags 2020-07-23T08:18:15.041100Z

1. I want both authenticaion and authorization (for example the ability to create non-expiring tuples would be a privilege in a certain space) 2. Tuple operations like read and take can both be blocking so this isn't a great fit to a regular HTTP API (I am also looking into Server Sent Events) and "template subscriptions" which I suspect are equivalent to query subscriptions might be an interesting idea. 3. Of course I need this at the API layer so you may be right if Biff is providing a web interface to some/all of this.

sandbags 2020-07-23T08:21:29.041400Z

I'm having a quick look at Crux. I am not very familiar with document databases although I broadly understand the concept.

sandbags 2020-07-23T08:22:02.041600Z

A document in my context could be [42,"What is six times seven?","See also: Answers to the ultimate question"] or ["=6*7"] or ["Douglas","Adams"] and so on and so forth

sandbags 2020-07-23T08:22:37.041800Z

Where a query to match it might be ["?integer","?","?string~=See also:"]

sandbags 2020-07-23T08:24:47.042200Z

I have a feeling that document databases tend to be optimised for JSON and index field: value type stuff where in my case there are no fields which might mean a whole database scan for a query.

2020-07-23T23:36:20.047400Z

hm, yeah. That could be difficult. Here's the best I can think of at the moment if you were to use Crux. You could use separate attributes for each tuple value, so [42, "foo", "bar"] could be modeled as {:crux.db/id #uuid "...", :0 42, :1 "foo", :2 "bar"}. Then a simple match like [42, "?", "?"] could be queried for with {:find '[doc] :where '[[doc :0 42]]} . To ensure that you only get tuples with three elements, you could do {:find '[doc] :where '[[doc :0 42] [doc :1] [doc :2] (not [doc :3])]} To query for "?integer", you could add type info, e.g. model the document like {:crux.db/id #uuid "...", :0 42, :type/0 :integer, :1 "foo", :type/1 :string, :2 "bar", :type/2 :string} . Then a query of ["?integer"] would be {:find '[doc] :where '[[doc :type/0 :integer] (not [doc :1])]} Querying for "?string~=See also:" would require a scan over all the tuples with string values in the appropriate positions. If this needs to be indexed, the options I see are: • ask on #crux about how hard it would be to add an index for text search • use datomic (https://docs.datomic.com/on-prem/query.html#fulltext) • roll your own indices • keep using SQL (if it's workable, might be the easiest option) In general, I bet the crux people would have a lot better advice about how you might go about implementing this. The general approach Biff takes to authn/authz and subscriptions might be helpful, though it does sound like it won't match your use case out of the box. Might be worth reading through the docs/source and playing with the example project just for understanding the approach.

sandbags 2020-07-24T07:58:48.054700Z

@foo thank you for such a well thought through response. It should have occurred to me that I could easily transform my tuples into a form more readily searchable in a doc db. That's good, I will have a think about that.

1👍