Added a very basic (partly functional) point system.
New users are started off with some free points, but can then earn more by giving feedback to other founders.
Points are given from survey owner to survey respondent.
But point system isn’t enforced, so users can earn points from a survey even if the survey owner doesn’t have any points left.
Playing it pretty loose with the point system in general until I know more about how people will really use it.
Added tags to the survey list to show what type of survey each one is (idea, landing-page, beta-user).
Survey text responses are now displayed in <pre> tags to allow for very basic formatting (really just newlines/paragraphs).
First beta-user signed up. I wasn’t planning to sign up beta-users until the point system was working, but couldn’t pass up the opportunity to get (extremely useful!) feedback. Thanks nlowell!
Researched what it would take to add client-side transactionality when updating a user value.
This came up because I’m using UserKit to store a Feedbacker user’s points in user.extras. We want to give some points from one user (the survey creator) to another user (the survey taker).
Example:
Two separate requests are made:
Remove 10 points from User A.
Give 10 points to User B.
If one of those requests fails, our users are left in an inconsistent state. User A may have 10 points less, but User B never received the points. They’re gone forever.
Solving the general case is possible. Here’s Guido Van Rossum’s solution for App Engine’s memcache implimentation.
It still requires significant work and understanding of transactions on part of our customers, which goes against our goal of simplifying their job as much as possible.
Although it solves the problem of ending up in an inconsistent state, race conditions still happen and can cause high failure rates depending on the use-case.
Solving specific cases would make it easier for the client.
For example, to transactionally subtract 10 points from user1.extras['points'] and give them to user2 we could do something like user1.transfer_to(user2, 'points', 10), or to increment a value transactionally: user1.extras.incr('points', 1).
Datastore transaction failure rates would still be high for some scenarios, but I’m hopeful that this would improve when Google migrates our datastore to firestore.
Will put this on back-burner for now, but feel more ready to handle this when it inevitably becomes an issue for one of our customers.
Misc
Wrote my bio for an AMA I’ll be doing. Was surprisingly hard to write a few sentences, but it’s probably a good exercise for any founder to go through.
Watered plants.
Ripened and froze a bunch of bananas for smoothies/smoothie-bowls.