's update for the week ending on Friday, Jul 12, 2019

Work

  • Caught up on support emails again after traveling. Managed to do a better job staying on top of back-and-forth’s this week.

Feedbacker

  • 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!

UserKit

  • 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:
          1. Remove 10 points from User A.
          1. 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.
 reacted with a 👍